1 /***
2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 */
4 package net.sourceforge.pmd.cpd;
5
6 import javax.swing.BorderFactory;
7 import javax.swing.JButton;
8 import javax.swing.JCheckBox;
9 import javax.swing.JComboBox;
10 import javax.swing.JFileChooser;
11 import javax.swing.JFrame;
12 import javax.swing.JLabel;
13 import javax.swing.JMenu;
14 import javax.swing.JMenuBar;
15 import javax.swing.JMenuItem;
16 import javax.swing.JOptionPane;
17 import javax.swing.JPanel;
18 import javax.swing.JProgressBar;
19 import javax.swing.JScrollPane;
20 import javax.swing.JTextArea;
21 import javax.swing.JTextField;
22 import javax.swing.Timer;
23 import java.awt.BorderLayout;
24 import java.awt.Dimension;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.io.File;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.io.PrintWriter;
31 import java.util.ArrayList;
32 import java.util.Iterator;
33 import java.util.List;
34
35 public class GUI implements CPDListener {
36
37 private static class CancelListener implements ActionListener {
38 public void actionPerformed(ActionEvent e) {
39 System.exit(0);
40 }
41 }
42
43 private class GoListener implements ActionListener {
44 public void actionPerformed(ActionEvent e) {
45 new Thread(new Runnable() {
46 public void run() {
47 tokenizingFilesBar.setValue(0);
48 tokenizingFilesBar.setString("");
49 resultsTextArea.setText("");
50 phaseLabel.setText("");
51 timeField.setText("");
52 go();
53 }
54 }).start();
55 }
56 }
57
58 private class SaveListener implements ActionListener {
59 public void actionPerformed(ActionEvent evt) {
60 int ret = fcSave.showSaveDialog(GUI.this.frame);
61 File f = fcSave.getSelectedFile();
62 if (f == null || ret != JFileChooser.APPROVE_OPTION) {
63 return;
64 }
65 if (!f.canWrite()) {
66 try {
67 PrintWriter pw = new PrintWriter(new FileOutputStream(f));
68 if (evt.getActionCommand().equals(".txt")) {
69 pw.write(new SimpleRenderer().render(matches.iterator()));
70 } else if (evt.getActionCommand().equals(".xml")) {
71 pw.write(new XMLRenderer().render(matches.iterator()));
72 } else if (evt.getActionCommand().equals(".csv")) {
73 pw.write(new CSVRenderer().render(matches.iterator()));
74 }
75 pw.flush();
76 pw.close();
77 JOptionPane.showMessageDialog(frame, "File saved");
78 } catch (IOException e) {
79 error("Couldn't save file" + f.getAbsolutePath(), e);
80 }
81 } else {
82 error("Could not write to file " + f.getAbsolutePath(), null);
83 }
84 }
85
86 private void error(String message, Exception e) {
87 if (e != null) {
88 e.printStackTrace();
89 }
90 JOptionPane.showMessageDialog(GUI.this.frame, message);
91 }
92
93 }
94
95 private class BrowseListener implements ActionListener {
96 public void actionPerformed(ActionEvent e) {
97 JFileChooser fc = new JFileChooser(rootDirectoryField.getText());
98 fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
99 fc.showDialog(frame, "Select");
100 if (fc.getSelectedFile() != null) {
101 rootDirectoryField.setText(fc.getSelectedFile().getAbsolutePath());
102 }
103 }
104 }
105
106 private JTextField rootDirectoryField = new JTextField(System.getProperty("user.home"));
107 private JTextField minimumLengthField = new JTextField("75");
108 private JTextField timeField = new JTextField(6);
109 private JLabel phaseLabel = new JLabel();
110 private JProgressBar tokenizingFilesBar = new JProgressBar();
111 private JTextArea resultsTextArea = new JTextArea();
112 private JCheckBox recurseCheckbox = new JCheckBox("", true);
113 private JComboBox languageBox = new JComboBox();
114 private JFileChooser fcSave = new JFileChooser();
115
116 private JFrame frame;
117
118 private List matches = new ArrayList();
119
120 public GUI() {
121 frame = new JFrame("PMD Cut and Paste Detector");
122
123 timeField.setEditable(false);
124
125 JMenu fileMenu = new JMenu("File");
126 fileMenu.setMnemonic('f');
127 JMenuItem saveItem = new JMenuItem("Save Text");
128 saveItem.setMnemonic('s');
129 saveItem.addActionListener(new SaveListener());
130 fileMenu.add(saveItem);
131 saveItem.setActionCommand(".txt");
132 saveItem = new JMenuItem("Save XML");
133 saveItem.addActionListener(new SaveListener());
134 fileMenu.add(saveItem);
135 saveItem.setActionCommand(".xml");
136 saveItem = new JMenuItem("Save CSV");
137 saveItem.setActionCommand(".csv");
138 saveItem.addActionListener(new SaveListener());
139 fileMenu.add(saveItem);
140 JMenuItem exitItem = new JMenuItem("Exit");
141 exitItem.setMnemonic('x');
142 exitItem.addActionListener(new CancelListener());
143 fileMenu.add(exitItem);
144 JMenuBar menuBar = new JMenuBar();
145 menuBar.add(fileMenu);
146 frame.setJMenuBar(menuBar);
147
148 // first make all the buttons
149 JButton browseButton = new JButton("Browse");
150 browseButton.setMnemonic('b');
151 browseButton.addActionListener(new BrowseListener());
152 JButton goButton = new JButton("Go");
153 goButton.setMnemonic('g');
154 goButton.addActionListener(new GoListener());
155 JButton cxButton = new JButton("Cancel");
156 cxButton.addActionListener(new CancelListener());
157
158 JPanel settingsPanel = makeSettingsPanel(browseButton, goButton, cxButton);
159 JPanel progressPanel = makeProgressPanel();
160 JPanel resultsPanel = makeResultsPanel();
161
162 frame.getContentPane().setLayout(new BorderLayout());
163 JPanel topPanel = new JPanel();
164 topPanel.setLayout(new BorderLayout());
165 topPanel.add(settingsPanel, BorderLayout.NORTH);
166 topPanel.add(progressPanel, BorderLayout.CENTER);
167 frame.getContentPane().add(topPanel, BorderLayout.NORTH);
168 frame.getContentPane().add(resultsPanel, BorderLayout.CENTER);
169 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
170 frame.pack();
171 frame.show();
172 }
173
174 private JPanel makeSettingsPanel(JButton browseButton, JButton goButton, JButton cxButton) {
175 JPanel settingsPanel = new JPanel();
176 GridBagHelper helper = new GridBagHelper(settingsPanel, new double[] { 0.2, 0.7, 0.1, 0.1 });
177 helper.addLabel("Root source directory:");
178 helper.add(rootDirectoryField);
179 helper.add(browseButton, 2);
180 helper.nextRow();
181 helper.addLabel("Minimum tile size:");
182 minimumLengthField.setColumns(4);
183 helper.add(minimumLengthField);
184 helper.addLabel("Language:");
185 languageBox.addItem("Java");
186 languageBox.addItem("C++");
187 languageBox.addItem("PHP");
188 helper.add(languageBox);
189 helper.nextRow();
190 helper.addLabel("Also scan subdirectories?");
191 helper.add(recurseCheckbox);
192 helper.add(goButton);
193 helper.add(cxButton);
194 helper.nextRow();
195 settingsPanel.setBorder(BorderFactory.createTitledBorder("Settings"));
196 return settingsPanel;
197 }
198
199 private JPanel makeProgressPanel() {
200 JPanel progressPanel = new JPanel();
201 final double[] weights = { 0.0, 0.8, 0.4, 0.2 };
202 GridBagHelper helper = new GridBagHelper(progressPanel, weights);
203 helper.addLabel("Tokenizing files:");
204 helper.add(tokenizingFilesBar, 3);
205 helper.nextRow();
206 helper.addLabel("Phase:");
207 helper.add(phaseLabel);
208 helper.addLabel("Time elapsed:");
209 helper.add(timeField);
210 helper.nextRow();
211 progressPanel.setBorder(BorderFactory.createTitledBorder("Progress"));
212 return progressPanel;
213 }
214
215 private JPanel makeResultsPanel() {
216 JPanel resultsPanel = new JPanel();
217 resultsPanel.setLayout(new BorderLayout());
218 JScrollPane areaScrollPane = new JScrollPane(resultsTextArea);
219 areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
220 areaScrollPane.setPreferredSize(new Dimension(600, 300));
221 resultsPanel.add(areaScrollPane, BorderLayout.CENTER);
222 resultsPanel.setBorder(BorderFactory.createTitledBorder("Results"));
223 return resultsPanel;
224 }
225
226 private void go() {
227 try {
228 if (!(new File(rootDirectoryField.getText())).exists()) {
229 JOptionPane.showMessageDialog(
230 frame,
231 "Can't read from that root source directory",
232 "Error",
233 JOptionPane.ERROR_MESSAGE);
234 return;
235 }
236
237 Language language = null;
238 LanguageFactory lf = new LanguageFactory();
239 if (languageBox.getSelectedItem().equals("Java")) {
240 language = lf.createLanguage(LanguageFactory.JAVA_KEY);
241 } else if (languageBox.getSelectedItem().equals("C++")) {
242 language = lf.createLanguage(LanguageFactory.CPP_KEY);
243 } else if (languageBox.getSelectedItem().equals("PHP")) {
244 language = lf.createLanguage(LanguageFactory.PHP_KEY);
245 }
246
247 CPD cpd = new CPD(Integer.parseInt(minimumLengthField.getText()), language);
248 cpd.setCpdListener(this);
249 tokenizingFilesBar.setMinimum(0);
250 phaseLabel.setText("");
251 if (rootDirectoryField.getText().endsWith(".class")
252 || rootDirectoryField.getText().endsWith(".php")
253 || rootDirectoryField.getText().endsWith(".java")
254 || rootDirectoryField.getText().endsWith(".cpp")
255 || rootDirectoryField.getText().endsWith(".c")) {
256 cpd.add(new File(rootDirectoryField.getText()));
257 } else {
258 if (recurseCheckbox.isSelected()) {
259 cpd.addRecursively(rootDirectoryField.getText());
260 } else {
261 cpd.addAllInDirectory(rootDirectoryField.getText());
262 }
263 }
264 final long start = System.currentTimeMillis();
265 Timer t = new Timer(1000, new ActionListener() {
266 public void actionPerformed(ActionEvent e) {
267 long now = System.currentTimeMillis();
268 long elapsedMillis = now - start;
269 long elapsedSeconds = elapsedMillis / 1000;
270 long hours = (long) Math.floor(elapsedSeconds / 3600);
271 long minutes = (long) Math.floor((elapsedSeconds - (hours * 3600)) / 60);
272 long seconds = elapsedSeconds - ((minutes * 60) + (hours * 3600));
273 timeField.setText(
274 ""
275 + munge(String.valueOf(hours))
276 + ":"
277 + munge(String.valueOf(minutes))
278 + ":"
279 + munge(String.valueOf(seconds)));
280 }
281 private String munge(String in) {
282 if (in.length() < 2) {
283 in = "0" + in;
284 }
285 return in;
286 }
287
288 });
289 t.start();
290 cpd.go();
291 t.stop();
292 matches = new ArrayList();
293 for (Iterator i = cpd.getMatches(); i.hasNext();) {
294 Match m = (Match) i.next();
295 matches.add(m);
296 }
297
298 String report = new SimpleRenderer().render(cpd.getMatches());
299 if (report.length() == 0) {
300 JOptionPane.showMessageDialog(
301 frame,
302 "Done; couldn't find any duplicates longer than " + minimumLengthField.getText() + " tokens");
303 } else {
304 resultsTextArea.setText(report);
305 }
306 } catch (Throwable t) {
307 t.printStackTrace();
308 JOptionPane.showMessageDialog(frame, "Halted due to " + t.getClass().getName() + "; " + t.getMessage());
309 }
310 }
311
312 // CPDListener
313 public void phaseUpdate(int phase) {
314 phaseLabel.setText(getPhaseText(phase));
315 }
316
317 public String getPhaseText(int phase) {
318 switch (phase) {
319 case CPDListener.INIT :
320 return "Initializing";
321 case CPDListener.HASH :
322 return "Hashing";
323 case CPDListener.MATCH :
324 return "Matching";
325 case CPDListener.GROUPING :
326 return "Grouping";
327 case CPDListener.DONE :
328 return "Done";
329 default :
330 return "Unknown";
331 }
332 }
333
334 public void addedFile(int fileCount, File file) {
335 tokenizingFilesBar.setMaximum(fileCount);
336 tokenizingFilesBar.setValue(tokenizingFilesBar.getValue() + 1);
337 }
338 // CPDListener
339
340 public static void main(String[] args) {
341 //this should prevent the disk not found popup
342 System.setSecurityManager(null);
343 new GUI();
344 }
345
346 }
This page was automatically generated by Maven