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                                    this.master = master;
068                            }
069    
070                            public String toString() {
071                                    return "["+tokenNames[master.getType()]+" "+master.getLine()+":"+master.getColumn()+"] "+ master.getText();
072                            }                       
073                            
074                            public int hashCode() {
075                                    return master.hashCode();
076                            }
077                            
078                            public boolean equals(Object obj) {
079                                    return obj instanceof Node && master.equals(((Node) obj).master);
080                            }
081                    }
082    
083                AST root = null;
084                    private String[] tokenNames;
085    
086                public JTreeASTModel(AST t, String[] tokenNames) {
087                    if (t == null) {
088                        throw new IllegalArgumentException("root is null");
089                    }
090                    root = t;
091                    this.tokenNames=tokenNames;
092                }
093    
094                public void addTreeModelListener(TreeModelListener l) {
095                }
096    
097                public Object getChild(Object parent, int index) {
098                    if (parent == null) {
099                        return null;
100                    }
101                    AST p = ((Node) parent).master;
102                    AST c = p.getFirstChild();
103                    if (c == null) {
104                        throw new ArrayIndexOutOfBoundsException("node has no children");
105                    }
106                    int i = 0;
107                    while (c != null && i < index) {
108                        c = c.getNextSibling();
109                        i++;
110                    }
111                    
112                    return new Node(c);
113                }
114    
115                public int getChildCount(Object parent) {
116                    if (parent == null) {
117                        throw new IllegalArgumentException("root is null");
118                    }
119                    AST p = ((Node)parent).master;
120                    AST c = p.getFirstChild();
121                    int i = 0;
122                    while (c != null) {
123                        c = c.getNextSibling();
124                        i++;
125                    }
126                    return i;
127                }
128    
129                public int getIndexOfChild(Object parent, Object child) {
130                    if (parent == null || child == null) {
131                        throw new IllegalArgumentException("root or child is null");
132                    }
133                    AST p = ((Node) parent).master;
134                    AST c = p.getFirstChild();
135                    if (c == null) {
136                        throw new ArrayIndexOutOfBoundsException("node has no children");
137                    }
138                    int i = 0;
139                    while (c != null && c != ((Node) child).master) {
140                        c = c.getNextSibling();
141                        i++;
142                    }
143                    if (c == ((Node) child).master) {
144                        return i;
145                    }
146                    throw new java.util.NoSuchElementException("node is not a child");
147                }
148    
149                public Object getRoot() {
150                    return new Node(root);
151                }
152    
153                public boolean isLeaf(Object node) {
154                    if (node == null) {
155                        throw new IllegalArgumentException("node is null");
156                    }
157                    AST t = ((Node) node).master;
158                    return t.getFirstChild() == null;
159                }
160    
161                public void removeTreeModelListener(TreeModelListener l) {
162                }
163    
164                public void valueForPathChanged(TreePath path, Object newValue) {
165                    System.out.println("heh, who is calling this mystery method?");
166                }
167            }               
168            
169        // The initial width and height of the frame
170        static final int FRAME_WIDTH = 400;
171        static final int FRAME_HEIGHT = 600;
172    
173        public ASTFrame(String lab, AST r, String[] tokenNames) {
174            super(lab);
175    
176            JTreeASTPanel tp = new JTreeASTPanel(new JTreeASTModel(r, tokenNames), null);
177            Container content = getContentPane();
178            content.add(tp, BorderLayout.CENTER);
179            addWindowListener(new WindowAdapter() {
180                public void windowClosing(WindowEvent e) {
181                    Frame f = (Frame)e.getSource();
182                    f.setVisible(false);
183                    f.dispose();
184                    // System.exit(0);
185                }
186            });
187            setSize(FRAME_WIDTH, FRAME_HEIGHT);
188        }
189    }