001 /**
002 * Borrowed from Terence Parr
003 */
004 package biz.hammurapi.antlr;
005
006 /* ANTLR Translator Generator
007 * Project led by Terence Parr at http://www.jGuru.com
008 * Software rights: http://www.antlr.org/license.html
009 *
010 * $Id: //depot/code/org.antlr/release/antlr-2.7.5/antlr/debug/misc/ASTFrame.java#1 $
011 */
012
013 import java.awt.BorderLayout;
014 import java.awt.Container;
015 import java.awt.Frame;
016 import java.awt.event.WindowAdapter;
017 import java.awt.event.WindowEvent;
018
019 import javax.swing.JFrame;
020 import javax.swing.JPanel;
021 import javax.swing.JScrollPane;
022 import javax.swing.JTree;
023 import javax.swing.event.TreeModelListener;
024 import javax.swing.event.TreeSelectionListener;
025 import javax.swing.tree.TreeModel;
026 import javax.swing.tree.TreePath;
027
028 import antlr.collections.AST;
029
030 public class ASTFrame extends JFrame {
031
032 public static class JTreeASTPanel extends JPanel {
033 JTree tree;
034
035 public JTreeASTPanel(TreeModel tm, TreeSelectionListener listener) {
036 // use a layout that will stretch tree to panel size
037 setLayout(new BorderLayout());
038
039 // Create tree
040 tree = new JTree(tm);
041
042 // Change line style
043 tree.putClientProperty("JTree.lineStyle", "Angled");
044
045 // Add TreeSelectionListener
046 if (listener != null)
047 tree.addTreeSelectionListener(listener);
048
049 // Put tree in a scrollable pane's viewport
050 JScrollPane sp = new JScrollPane();
051 sp.getViewport().add(tree);
052
053 add(sp, BorderLayout.CENTER);
054 }
055 }
056
057 public static class JTreeASTModel implements TreeModel {
058
059 private class Node {
060 AST master;
061
062 /**
063 * @param master
064 */
065 public Node(AST master) {
066 super();
067 // TODO Auto-generated constructor stub
068 this.master = master;
069 }
070
071 public String toString() {
072 return "["+tokenNames[master.getType()]+" "+master.getLine()+":"+master.getColumn()+"] "+ master.getText();
073 }
074
075 public int hashCode() {
076 return master.hashCode();
077 }
078
079 public boolean equals(Object obj) {
080 return obj instanceof Node && master.equals(((Node) obj).master);
081 }
082 }
083
084 AST root = null;
085 private String[] tokenNames;
086
087 public JTreeASTModel(AST t, String[] tokenNames) {
088 if (t == null) {
089 throw new IllegalArgumentException("root is null");
090 }
091 root = t;
092 this.tokenNames=tokenNames;
093 }
094
095 public void addTreeModelListener(TreeModelListener l) {
096 }
097
098 public Object getChild(Object parent, int index) {
099 if (parent == null) {
100 return null;
101 }
102 AST p = ((Node) parent).master;
103 AST c = p.getFirstChild();
104 if (c == null) {
105 throw new ArrayIndexOutOfBoundsException("node has no children");
106 }
107 int i = 0;
108 while (c != null && i < index) {
109 c = c.getNextSibling();
110 i++;
111 }
112
113 return new Node(c);
114 }
115
116 public int getChildCount(Object parent) {
117 if (parent == null) {
118 throw new IllegalArgumentException("root is null");
119 }
120 AST p = ((Node)parent).master;
121 AST c = p.getFirstChild();
122 int i = 0;
123 while (c != null) {
124 c = c.getNextSibling();
125 i++;
126 }
127 return i;
128 }
129
130 public int getIndexOfChild(Object parent, Object child) {
131 if (parent == null || child == null) {
132 throw new IllegalArgumentException("root or child is null");
133 }
134 AST p = ((Node) parent).master;
135 AST c = p.getFirstChild();
136 if (c == null) {
137 throw new ArrayIndexOutOfBoundsException("node has no children");
138 }
139 int i = 0;
140 while (c != null && c != ((Node) child).master) {
141 c = c.getNextSibling();
142 i++;
143 }
144 if (c == ((Node) child).master) {
145 return i;
146 }
147 throw new java.util.NoSuchElementException("node is not a child");
148 }
149
150 public Object getRoot() {
151 return new Node(root);
152 }
153
154 public boolean isLeaf(Object node) {
155 if (node == null) {
156 throw new IllegalArgumentException("node is null");
157 }
158 AST t = ((Node) node).master;
159 return t.getFirstChild() == null;
160 }
161
162 public void removeTreeModelListener(TreeModelListener l) {
163 }
164
165 public void valueForPathChanged(TreePath path, Object newValue) {
166 System.out.println("heh, who is calling this mystery method?");
167 }
168 }
169
170 // The initial width and height of the frame
171 static final int FRAME_WIDTH = 400;
172 static final int FRAME_HEIGHT = 600;
173
174 public ASTFrame(String lab, AST r, String[] tokenNames) {
175 super(lab);
176
177 JTreeASTPanel tp = new JTreeASTPanel(new JTreeASTModel(r, tokenNames), null);
178 Container content = getContentPane();
179 content.add(tp, BorderLayout.CENTER);
180 addWindowListener(new WindowAdapter() {
181 public void windowClosing(WindowEvent e) {
182 Frame f = (Frame)e.getSource();
183 f.setVisible(false);
184 f.dispose();
185 // System.exit(0);
186 }
187 });
188 setSize(FRAME_WIDTH, FRAME_HEIGHT);
189 }
190 }