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    }