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).setVisible(true); 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 }