001 package org.codehaus.groovy.antlr;
002 import java.awt.*;
003 import java.awt.event.*;
004 import java.io.*;
005 import java.lang.reflect.*;
006 import java.util.Hashtable;
007
008 import javax.swing.*;
009 import javax.swing.border.Border;
010 import javax.swing.text.BadLocationException;
011 import org.codehaus.groovy.antlr.parser.*;
012
013 import antlr.*;
014
015 /**
016 * @author Santhosh Kumar T
017 * @version 1.0
018 */
019
020 public class LexerFrame extends JFrame implements ActionListener{
021 JSplitPane jSplitPane1 = new JSplitPane();
022 JScrollPane jScrollPane1 = new JScrollPane();
023 JScrollPane jScrollPane2 = new JScrollPane();
024 JTextPane tokenPane = new HScrollableTextPane();
025 JButton jbutton = new JButton("open");
026 JPanel mainPanel = new JPanel(new BorderLayout());
027 JTextArea scriptPane = new JTextArea();
028 Border border1;
029 Border border2;
030
031 Class lexerClass;
032
033 public LexerFrame(Class lexerClass, Class tokenTypesClass){
034 super("Token Steam Viewer");
035 this.lexerClass = lexerClass;
036 try{
037 jbInit();
038 setSize(500, 500);
039 listTokens(tokenTypesClass);
040
041 final JPopupMenu popup = new JPopupMenu();
042 popup.add(loadFileAction);
043
044 jbutton.setSize(30,30);
045 jbutton.addMouseListener(new MouseAdapter(){
046 public void mouseReleased(MouseEvent e) {
047 //if(e.isPopupTrigger())
048 popup.show(scriptPane, e.getX(), e.getY());
049 }
050 });
051 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
052 } catch(Exception e){
053 e.printStackTrace();
054 }
055 }
056
057 Hashtable tokens = new Hashtable();
058
059 private void listTokens(Class tokenTypes) throws Exception{
060 Field field[] = tokenTypes.getDeclaredFields();
061 for(int i = 0; i<field.length; i++)
062 tokens.put(field[i].get(null), field[i].getName());
063 }
064
065 public void actionPerformed(ActionEvent ae){
066 Token token = (Token) ((JComponent) ae.getSource()).getClientProperty("token");
067 if(token.getType()==Token.EOF_TYPE){
068 scriptPane.select(0, 0);
069 return;
070 }
071 try{
072 int start = scriptPane.getLineStartOffset(token.getLine()-1)+token.getColumn()-1;
073 scriptPane.select(start, start+token.getText().length());
074 scriptPane.requestFocus();
075 } catch(BadLocationException ex){
076 }
077 }
078
079 private Action loadFileAction = new AbstractAction("Open File..."){
080 public void actionPerformed(ActionEvent ae){
081 JFileChooser jfc = new JFileChooser();
082 int response = jfc.showOpenDialog(LexerFrame.this);
083 if(response!=JFileChooser.APPROVE_OPTION)
084 return;
085 try{
086 scanScript(jfc.getSelectedFile());
087 } catch(Exception ex){
088 ex.printStackTrace();
089 }
090 }
091 };
092
093 private void scanScript(File file) throws Exception{
094 scriptPane.read(new FileReader(file), null);
095
096 // create lexer
097 Constructor constructor = lexerClass.getConstructor(new Class[]{InputStream.class});
098 CharScanner lexer = (CharScanner) constructor.newInstance(new Object[]{new FileInputStream(file)});
099
100 tokenPane.setEditable(true);
101 tokenPane.setText("");
102
103 int line = 1;
104 ButtonGroup bg = new ButtonGroup();
105 Token token = null;
106
107 while(true){
108 token = lexer.nextToken();
109 JToggleButton tokenButton = new JToggleButton((String) tokens.get(new Integer(token.getType())));
110 bg.add(tokenButton);
111 tokenButton.addActionListener(this);
112 tokenButton.setToolTipText(token.getText());
113 tokenButton.putClientProperty("token", token);
114 tokenButton.setMargin(new Insets(0, 1, 0, 1));
115 tokenButton.setFocusPainted(false);
116 if(token.getLine()>line){
117 tokenPane.getDocument().insertString(tokenPane.getDocument().getLength(), "\n", null);
118 line = token.getLine();
119 }
120 insertComponent(tokenButton);
121 if(token.getType()==Token.EOF_TYPE)
122 break;
123 }
124
125 tokenPane.setEditable(false);
126 tokenPane.setCaretPosition(0);
127 }
128
129 private void insertComponent(JComponent comp){
130 try{
131 tokenPane.getDocument().insertString(tokenPane.getDocument().getLength(), " ", null);
132 } catch(BadLocationException ex1){
133 }
134 try{
135 tokenPane.setCaretPosition(tokenPane.getDocument().getLength()-1);
136 } catch(Exception ex){
137 tokenPane.setCaretPosition(0);
138 }
139 tokenPane.insertComponent(comp);
140 }
141
142 private void jbInit() throws Exception{
143 border1 = BorderFactory.createEmptyBorder();
144 border2 = BorderFactory.createEmptyBorder();
145 jSplitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT);
146 tokenPane.setEditable(false);
147 tokenPane.setText("");
148 scriptPane.setFont(new java.awt.Font("DialogInput", 0, 12));
149 scriptPane.setEditable(false);
150 scriptPane.setMargin(new Insets(5, 5, 5, 5));
151 scriptPane.setText("");
152 jScrollPane1.setBorder(border1);
153 jScrollPane2.setBorder(border1);
154 jSplitPane1.setMinimumSize(new Dimension(800,600));
155 mainPanel.add(jSplitPane1, BorderLayout.CENTER);
156 mainPanel.add(jbutton,BorderLayout.NORTH);
157 this.getContentPane().add(mainPanel);
158 jSplitPane1.add(jScrollPane1, JSplitPane.LEFT);
159 jScrollPane1.getViewport().add(tokenPane, null);
160 jSplitPane1.add(jScrollPane2, JSplitPane.RIGHT);
161 jScrollPane2.getViewport().add(scriptPane, null);
162
163 jScrollPane1.setColumnHeaderView(new JLabel(" Token Stream:"));
164 jScrollPane2.setColumnHeaderView(new JLabel(" Input Script:"));
165 jSplitPane1.setResizeWeight(0.5);
166 }
167
168 public static void main(String[] args) throws Exception{
169 try{
170 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
171 } catch(Exception ignore){
172 }
173 new LexerFrame(GroovyLexer.class, GroovyTokenTypes.class).show();
174 }
175 }
176
177
178 class HScrollableTextPane extends JTextPane{
179 public boolean getScrollableTracksViewportWidth(){
180 return(getSize().width<getParent().getSize().width);
181 }
182
183 public void setSize(Dimension d){
184 if(d.width<getParent().getSize().width){
185 d.width = getParent().getSize().width;
186 }
187 super.setSize(d);
188 }
189 }