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.JMenu;
13 import javax.swing.JMenuBar;
14 import javax.swing.JMenuItem;
15 import javax.swing.JOptionPane;
16 import javax.swing.JPanel;
17 import javax.swing.JProgressBar;
18 import javax.swing.JScrollPane;
19 import javax.swing.JTextArea;
20 import javax.swing.JTextField;
21 import javax.swing.Timer;
22 import java.awt.BorderLayout;
23 import java.awt.Dimension;
24 import java.awt.FileDialog;
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
32 public class GUI implements CPDListener {
33
34 private static class CancelListener implements ActionListener {
35 public void actionPerformed(ActionEvent e) {
36 System.exit(0);
37 }
38 }
39
40 private class GoListener implements ActionListener {
41 public void actionPerformed(ActionEvent e) {
42 new Thread(new Runnable() {
43 public void run() {
44 tokenizingFilesBar.setValue(0);
45 tokenizingFilesBar.setString("");
46 resultsTextArea.setText("");
47 comparisonsField.setText("");
48 timeField.setText("");
49 go();
50 }
51 }).start();
52 }
53 }
54
55 private class SaveListener implements ActionListener {
56 public void actionPerformed(ActionEvent evt){
57 FileDialog fdlg = new FileDialog(GUI.this.frame, "Save", FileDialog.SAVE);
58 fdlg.setVisible(true);
59 String selected = fdlg.getDirectory() + System.getProperty("file.separator") + fdlg.getFile();
60 if (fdlg.getFile() == null) {
61 return;
62 }
63 if(!new File(selected).canWrite()){
64 try{
65 PrintWriter pw = new PrintWriter(new FileOutputStream(selected));
66 String report = resultsTextArea.getText();
67 pw.print(report);
68 pw.flush();
69 pw.close();
70 JOptionPane.showMessageDialog(frame, "File saved");
71 }catch(IOException e){
72 error("Couldn't save file"+new File(selected).getAbsolutePath(), e);
73 }
74 }else{
75 error("Could not write to file "+new File(selected).getAbsolutePath(), null);
76 }
77 }
78
79 private void error(String message, Exception e){
80 if(e != null){
81 e.printStackTrace();
82 }
83 JOptionPane.showMessageDialog(GUI.this.frame, message);
84 }
85
86 }
87
88 private class BrowseListener implements ActionListener {
89 public void actionPerformed(ActionEvent e) {
90 JFileChooser fc = new JFileChooser(rootDirectoryField.getText());
91 fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
92 fc.showDialog(frame, "Select");
93 if (fc.getSelectedFile() != null) {
94 rootDirectoryField.setText(fc.getSelectedFile().getAbsolutePath());
95 }
96 }
97 }
98
99 private JTextField rootDirectoryField = new JTextField(System.getProperty("user.home"));
100 private JTextField minimumLengthField = new JTextField("75");
101 private JTextField timeField = new JTextField(6);
102 private JTextField comparisonsField = new JTextField(8);
103 private JProgressBar tokenizingFilesBar = new JProgressBar();
104 private JTextArea resultsTextArea = new JTextArea();
105 private JCheckBox recurseCheckbox = new JCheckBox("", true);
106 private JComboBox languageBox = new JComboBox();
107
108 private JFrame frame;
109
110 public GUI() {
111 frame = new JFrame("PMD Cut and Paste Detector");
112
113 timeField.setEditable(false);
114 comparisonsField.setEditable(false);
115
116 JMenu fileMenu = new JMenu("File");
117 fileMenu.setMnemonic('f');
118 JMenuItem saveItem = new JMenuItem("Save");
119 saveItem.setMnemonic('s');
120 saveItem.addActionListener(new SaveListener());
121 fileMenu.add(saveItem); JMenuItem exitItem = new JMenuItem("Exit");
122 exitItem.setMnemonic('x');
123 exitItem.addActionListener(new CancelListener());
124 fileMenu.add(exitItem);
125 JMenuBar menuBar = new JMenuBar();
126 menuBar.add(fileMenu);
127 frame.setJMenuBar(menuBar);
128
129 // first make all the buttons
130 JButton browseButton = new JButton("Browse");
131 browseButton.setMnemonic('b');
132 browseButton.addActionListener(new BrowseListener());
133 JButton goButton = new JButton("Go");
134 goButton.setMnemonic('g');
135 goButton.addActionListener(new GoListener());
136 JButton cxButton = new JButton("Cancel");
137 cxButton.addActionListener(new CancelListener());
138
139 JPanel settingsPanel = makeSettingsPanel(browseButton, goButton, cxButton);
140 JPanel progressPanel = makeProgressPanel();
141 JPanel resultsPanel = makeResultsPanel();
142
143 frame.getContentPane().setLayout(new BorderLayout());
144 JPanel topPanel = new JPanel();
145 topPanel.setLayout(new BorderLayout());
146 topPanel.add(settingsPanel, BorderLayout.NORTH);
147 topPanel.add(progressPanel, BorderLayout.CENTER);
148 frame.getContentPane().add(topPanel, BorderLayout.NORTH);
149 frame.getContentPane().add(resultsPanel, BorderLayout.CENTER);
150 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
151 frame.pack();
152 frame.show();
153 }
154
155 private JPanel makeSettingsPanel(JButton browseButton, JButton goButton, JButton cxButton) {
156 JPanel settingsPanel = new JPanel();
157 GridBagHelper helper = new GridBagHelper(settingsPanel, new double[]{0.2, 0.7, 0.1, 0.1});
158 helper.addLabel("Root source directory:");
159 helper.add(rootDirectoryField);
160 helper.add(browseButton, 2);
161 helper.nextRow();
162 helper.addLabel("Minimum tile size:");
163 minimumLengthField.setColumns(4);
164 helper.add(minimumLengthField);
165 helper.addLabel("Language:");
166 languageBox.addItem("Java");
167 languageBox.addItem("C++");
168 languageBox.addItem("PHP");
169 helper.add(languageBox);
170 helper.nextRow();
171 helper.addLabel("Also scan subdirectories?");
172 helper.add(recurseCheckbox);
173 helper.add(goButton);
174 helper.add(cxButton);
175 helper.nextRow();
176 settingsPanel.setBorder(BorderFactory.createTitledBorder("Settings"));
177 return settingsPanel;
178 }
179
180 private JPanel makeProgressPanel() {
181 JPanel progressPanel = new JPanel();
182 final double[] weights = {0.0, 0.8, 0.4, 0.2};
183 GridBagHelper helper = new GridBagHelper(progressPanel, weights);
184 helper.addLabel("Tokenizing files:");
185 helper.add(tokenizingFilesBar, 3);
186 helper.nextRow();
187 helper.addLabel("Comparisons so far:");
188 helper.add(comparisonsField);
189 helper.addLabel("Time elapsed:");
190 helper.add(timeField);
191 helper.nextRow();
192 progressPanel.setBorder(BorderFactory.createTitledBorder("Progress"));
193 return progressPanel;
194 }
195
196 private JPanel makeResultsPanel() {
197 JPanel resultsPanel = new JPanel();
198 resultsPanel.setLayout(new BorderLayout());
199 JScrollPane areaScrollPane = new JScrollPane(resultsTextArea);
200 areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
201 areaScrollPane.setPreferredSize(new Dimension(600, 300));
202 resultsPanel.add(areaScrollPane, BorderLayout.CENTER);
203 resultsPanel.setBorder(BorderFactory.createTitledBorder("Results"));
204 return resultsPanel;
205 }
206
207 private void go() {
208 try {
209 if (!(new File(rootDirectoryField.getText())).exists()) {
210 JOptionPane.showMessageDialog(frame, "Can't read from that root source directory", "Error", JOptionPane.ERROR_MESSAGE);
211 return;
212 }
213
214 Language language = null;
215 LanguageFactory lf = new LanguageFactory();
216 if (languageBox.getSelectedItem().equals("Java")) {
217 language = lf.createLanguage(LanguageFactory.JAVA_KEY);
218 } else if (languageBox.getSelectedItem().equals("C++")) {
219 language = lf.createLanguage(LanguageFactory.CPP_KEY);
220 } else if (languageBox.getSelectedItem().equals("PHP")) {
221 language = lf.createLanguage(LanguageFactory.PHP_KEY);
222 }
223
224 CPD cpd = new CPD(Integer.parseInt(minimumLengthField.getText()), language);
225 cpd.setCpdListener(this);
226 tokenizingFilesBar.setMinimum(0);
227 comparisonsField.setText("");
228 if (rootDirectoryField.getText().endsWith(".class") || rootDirectoryField.getText().endsWith(".php") || rootDirectoryField.getText().endsWith(".java") || rootDirectoryField.getText().endsWith(".cpp") || rootDirectoryField.getText().endsWith(".c")) {
229 cpd.add(new File(rootDirectoryField.getText()));
230 } else {
231 if (recurseCheckbox.isSelected()) {
232 cpd.addRecursively(rootDirectoryField.getText());
233 } else {
234 cpd.addAllInDirectory(rootDirectoryField.getText());
235 }
236 }
237 final long start = System.currentTimeMillis();
238 Timer t = new Timer(1000, new ActionListener() {
239 public void actionPerformed(ActionEvent e) {
240 long now = System.currentTimeMillis();
241 long elapsedMillis = now - start;
242 long elapsedSeconds = elapsedMillis / 1000;
243 long hours = (long) Math.floor(elapsedSeconds / 3600);
244 long minutes = (long) Math.floor((elapsedSeconds - (hours * 3600)) / 60);
245 long seconds = elapsedSeconds - ((minutes * 60) + (hours * 3600));
246 timeField.setText("" + munge(String.valueOf(hours)) + ":" + munge(String.valueOf(minutes)) + ":" + munge(String.valueOf(seconds)));
247 }
248 private String munge(String in) {
249 if (in.length() < 2) {
250 in = "0" + in;
251 }
252 return in;
253 }
254
255 });
256 t.start();
257 cpd.go();
258 t.stop();
259 String report = new SimpleRenderer().render(cpd.getMatches());
260 if (report.length() == 0) {
261 JOptionPane.showMessageDialog(frame, "Done; couldn't find any duplicates longer than " + minimumLengthField.getText() + " tokens");
262 } else {
263 resultsTextArea.setText(report);
264 }
265 } catch (Throwable t) {
266 t.printStackTrace();
267 JOptionPane.showMessageDialog(frame, "Halted due to " + t.getClass().getName() + "; " + t.getMessage());
268 }
269 }
270
271 // CPDListener
272 public void comparisonCountUpdate(long comparisons) {
273 comparisonsField.setText(String.valueOf(comparisons));
274 }
275
276 public void addedFile(int fileCount, File file) {
277 tokenizingFilesBar.setMaximum(fileCount);
278 tokenizingFilesBar.setValue(tokenizingFilesBar.getValue() + 1);
279 }
280 // CPDListener
281
282 public static void main(String[] args) {
283 new GUI();
284 }
285
286 }
This page was automatically generated by Maven