1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.gui;
21
22 import java.awt.BorderLayout;
23 import java.awt.Component;
24 import java.awt.GridLayout;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.KeyEvent;
27 import java.io.File;
28 import java.io.IOException;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.TooManyListenersException;
32
33 import javax.swing.AbstractAction;
34 import javax.swing.Action;
35 import javax.swing.JButton;
36 import javax.swing.JFileChooser;
37 import javax.swing.JOptionPane;
38 import javax.swing.JPanel;
39 import javax.swing.JScrollPane;
40 import javax.swing.JTextArea;
41 import javax.swing.SwingUtilities;
42 import javax.swing.filechooser.FileFilter;
43
44 import antlr.ANTLRException;
45
46 import com.puppycrawl.tools.checkstyle.TreeWalker;
47 import com.puppycrawl.tools.checkstyle.api.DetailAST;
48 import com.puppycrawl.tools.checkstyle.api.FileContents;
49 import com.puppycrawl.tools.checkstyle.api.FileText;
50
51
52
53
54
55
56
57
58 public class ParseTreeInfoPanel extends JPanel
59 {
60
61 private static final long serialVersionUID = -4243405131202059043L;
62 private final JTreeTable treeTable;
63 private final ParseTreeModel parseTreeModel;
64 private final JTextArea jTextArea;
65 private File lastDirectory = null;
66 private File currentFile = null;
67 private final Action reloadAction;
68 private final List<Integer> lines2position = new ArrayList<>();
69
70 private static class JavaFileFilter extends FileFilter
71 {
72 @Override
73 public boolean accept(File f)
74 {
75 if (f == null) {
76 return false;
77 }
78 return f.isDirectory() || f.getName().endsWith(".java");
79 }
80
81 @Override
82 public String getDescription()
83 {
84 return "Java Source Code";
85 }
86 }
87
88 public void openAst(DetailAST parseTree, final Component parent)
89 {
90 parseTreeModel.setParseTree(parseTree);
91 reloadAction.setEnabled(true);
92
93
94 getLines2position().clear();
95
96 getLines2position().add(0);
97
98
99
100 if (jTextArea.getText().length() != 0) {
101 jTextArea.replaceRange("", 0, jTextArea.getText().length());
102 }
103
104
105 jTextArea.moveCaretPosition(0);
106 }
107
108 private class FileSelectionAction extends AbstractAction
109 {
110
111
112
113 private static final long serialVersionUID = -1926935338069418119L;
114
115 public FileSelectionAction()
116 {
117 super("Select Java File");
118 putValue(Action.MNEMONIC_KEY, KeyEvent.VK_S);
119 }
120
121 @Override
122 public void actionPerformed(ActionEvent e)
123 {
124 final JFileChooser fc = new JFileChooser( lastDirectory );
125 final FileFilter filter = new JavaFileFilter();
126 fc.setFileFilter(filter);
127 final Component parent =
128 SwingUtilities.getRoot(ParseTreeInfoPanel.this);
129 fc.showDialog(parent, "Open");
130 final File file = fc.getSelectedFile();
131 openFile(file, parent);
132
133 }
134 }
135
136 private class ReloadAction extends AbstractAction
137 {
138
139
140
141 private static final long serialVersionUID = -1021880396046355863L;
142
143 public ReloadAction()
144 {
145 super("Reload Java File");
146 putValue(Action.MNEMONIC_KEY, KeyEvent.VK_R);
147 }
148
149 @Override
150 public void actionPerformed(ActionEvent e)
151 {
152 final Component parent =
153 SwingUtilities.getRoot(ParseTreeInfoPanel.this);
154 openFile(currentFile, parent);
155 }
156 }
157
158
159 private class FileDropListener implements FileDrop.Listener
160 {
161 private final JScrollPane mSp;
162
163 @Override
164 public void filesDropped(File[] files)
165 {
166 if (files != null && files.length > 0)
167 {
168 final File file = files[0];
169 openFile(file, mSp);
170 }
171 }
172
173 public FileDropListener(JScrollPane aSp)
174 {
175 mSp = aSp;
176 }
177 }
178
179
180 public void openFile(File file, final Component parent)
181 {
182 if (file != null) {
183 try {
184 Main.frame.setTitle("Checkstyle : " + file.getName());
185 final FileText text = new FileText(file.getAbsoluteFile(),
186 getEncoding());
187 final DetailAST parseTree = parseFile(text);
188 parseTreeModel.setParseTree(parseTree);
189 currentFile = file;
190 lastDirectory = file.getParentFile();
191 reloadAction.setEnabled(true);
192
193 final String[] sourceLines = text.toLinesArray();
194
195
196 getLines2position().clear();
197
198 getLines2position().add(0);
199
200 for (String element : sourceLines)
201 {
202 getLines2position().add(jTextArea.getText().length());
203 jTextArea.append(element + "\n");
204 }
205
206
207 if (jTextArea.getText().length() != 0) {
208 jTextArea.replaceRange("", 0, jTextArea.getText()
209 .length());
210 }
211
212
213 for (final String element : sourceLines) {
214 jTextArea.append(element + "\n");
215 }
216
217
218 jTextArea.moveCaretPosition(0);
219 }
220 catch (final IOException ex) {
221 showErrorDialog(
222 parent,
223 "Could not open " + file + ": " + ex.getMessage());
224 }
225 catch (final ANTLRException ex) {
226 showErrorDialog(
227 parent,
228 "Could not parse " + file + ": " + ex.getMessage());
229 }
230 }
231 }
232
233
234
235
236
237
238
239
240
241 @Deprecated
242 public static DetailAST parseFile(String fileName)
243 throws IOException, ANTLRException
244 {
245 return parseFile(new FileText(new File(fileName), getEncoding()));
246 }
247
248
249
250
251
252
253
254 public static DetailAST parseFile(FileText text)
255 throws ANTLRException
256 {
257 final FileContents contents = new FileContents(text);
258 return TreeWalker.parse(contents);
259 }
260
261
262
263
264
265
266
267 private static String getEncoding()
268 {
269 return System.getProperty("file.encoding", "UTF-8");
270 }
271
272
273
274
275 public ParseTreeInfoPanel()
276 {
277 setLayout(new BorderLayout());
278
279 final DetailAST treeRoot = null;
280 parseTreeModel = new ParseTreeModel(treeRoot);
281 treeTable = new JTreeTable(parseTreeModel);
282 final JScrollPane sp = new JScrollPane(treeTable);
283 this.add(sp, BorderLayout.NORTH);
284
285 final JButton fileSelectionButton =
286 new JButton(new FileSelectionAction());
287
288 reloadAction = new ReloadAction();
289 reloadAction.setEnabled(false);
290 final JButton reloadButton = new JButton(reloadAction);
291
292 jTextArea = new JTextArea(20, 15);
293 jTextArea.setEditable(false);
294 treeTable.setEditor(jTextArea);
295 treeTable.setLinePositionMap(lines2position);
296
297 final JScrollPane sp2 = new JScrollPane(jTextArea);
298 this.add(sp2, BorderLayout.CENTER);
299
300 final JPanel p = new JPanel(new GridLayout(1,2));
301 this.add(p, BorderLayout.SOUTH);
302 p.add(fileSelectionButton);
303 p.add(reloadButton);
304
305 try {
306
307
308 new FileDrop(sp, new FileDropListener(sp));
309 }
310 catch (final TooManyListenersException ex)
311 {
312 showErrorDialog(null, "Cannot initialize Drag and Drop support");
313 }
314
315 }
316
317 private void showErrorDialog(final Component parent, final String msg)
318 {
319 final Runnable showError = new Runnable()
320 {
321 @Override
322 public void run()
323 {
324 JOptionPane.showMessageDialog(parent, msg);
325 }
326 };
327 SwingUtilities.invokeLater(showError);
328 }
329
330 public List<Integer> getLines2position()
331 {
332 return lines2position;
333 }
334 }
335