KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > pmd > cpd > GUI


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.*;
7 import javax.swing.event.ListSelectionEvent JavaDoc;
8 import javax.swing.event.ListSelectionListener JavaDoc;
9 import javax.swing.event.TableModelListener JavaDoc;
10 import javax.swing.table.DefaultTableCellRenderer JavaDoc;
11 import javax.swing.table.JTableHeader JavaDoc;
12 import javax.swing.table.TableColumn JavaDoc;
13 import javax.swing.table.TableColumnModel JavaDoc;
14 import javax.swing.table.TableModel JavaDoc;
15 import java.awt.BorderLayout JavaDoc;
16 import java.awt.Component JavaDoc;
17 import java.awt.Dimension JavaDoc;
18 import java.awt.Point JavaDoc;
19 import java.awt.Toolkit JavaDoc;
20 import java.awt.datatransfer.StringSelection JavaDoc;
21 import java.awt.event.ActionEvent JavaDoc;
22 import java.awt.event.ActionListener JavaDoc;
23 import java.awt.event.ItemEvent JavaDoc;
24 import java.awt.event.ItemListener JavaDoc;
25 import java.awt.event.KeyEvent JavaDoc;
26 import java.awt.event.MouseAdapter JavaDoc;
27 import java.awt.event.MouseEvent JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.FileOutputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.PrintWriter JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.Collections JavaDoc;
34 import java.util.Comparator JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.HashSet JavaDoc;
37 import java.util.Iterator JavaDoc;
38 import java.util.List JavaDoc;
39 import java.util.Map JavaDoc;
40 import java.util.Properties JavaDoc;
41 import java.util.Set JavaDoc;
42
43 public class GUI implements CPDListener {
44
45     private interface Renderer {
46         String JavaDoc render(Iterator JavaDoc items);
47     }
48     
49     private static final Object JavaDoc[][] rendererSets = new Object JavaDoc[][] {
50         { "Text", new Renderer() { public String JavaDoc render(Iterator JavaDoc items) { return new SimpleRenderer().render(items); } } },
51         { "XML", new Renderer() { public String JavaDoc render(Iterator JavaDoc items) { return new XMLRenderer().render(items); } } },
52         { "CSV (comma)",new Renderer() { public String JavaDoc render(Iterator JavaDoc items) { return new CSVRenderer(',').render(items); } } },
53         { "CSV (tab)", new Renderer() { public String JavaDoc render(Iterator JavaDoc items) { return new CSVRenderer('\t').render(items); } } }
54         };
55     
56     private interface LanguageConfig {
57         Language languageFor(LanguageFactory lf, Properties JavaDoc p);
58         boolean ignoreLiteralsByDefault();
59         String JavaDoc[] extensions();
60     };
61     
62     private static final Object JavaDoc[][] languageSets = new Object JavaDoc[][] {
63         {"Java", new LanguageConfig() {
64                                     public Language languageFor(LanguageFactory lf, Properties JavaDoc p) { return lf.createLanguage(LanguageFactory.JAVA_KEY); }
65                                     public boolean ignoreLiteralsByDefault() { return true; }
66                                     public String JavaDoc[] extensions() { return new String JavaDoc[] {".java", ".class" }; }; } },
67         {"JSP", new LanguageConfig() {
68                                     public Language languageFor(LanguageFactory lf, Properties JavaDoc p) { return lf.createLanguage(LanguageFactory.JSP_KEY); }
69                                     public boolean ignoreLiteralsByDefault() { return false; }
70                                     public String JavaDoc[] extensions() { return new String JavaDoc[] {".jsp" }; }; } },
71         {"C++", new LanguageConfig() {
72                                     public Language languageFor(LanguageFactory lf, Properties JavaDoc p) { return lf.createLanguage(LanguageFactory.CPP_KEY); }
73                                     public boolean ignoreLiteralsByDefault() { return false; }
74                                     public String JavaDoc[] extensions() { return new String JavaDoc[] {".cpp", ".c" }; }; } },
75         {"Ruby", new LanguageConfig() {
76                                     public Language languageFor(LanguageFactory lf, Properties JavaDoc p) { return lf.createLanguage(LanguageFactory.RUBY_KEY); }
77                                     public boolean ignoreLiteralsByDefault() { return false; }
78                                     public String JavaDoc[] extensions() { return new String JavaDoc[] {".rb" }; }; } },
79         {"by extension...", new LanguageConfig() {
80                                     public Language languageFor(LanguageFactory lf, Properties JavaDoc p) { return lf.createLanguage(LanguageFactory.BY_EXTENSION, p); }
81                                     public boolean ignoreLiteralsByDefault() { return false; }
82                                     public String JavaDoc[] extensions() { return new String JavaDoc[] {"" }; }; } },
83         {"PHP", new LanguageConfig() {
84                                     public Language languageFor(LanguageFactory lf, Properties JavaDoc p) { return lf.createLanguage(LanguageFactory.PHP_KEY); }
85                                     public boolean ignoreLiteralsByDefault() { return false; }
86                                     public String JavaDoc[] extensions() { return new String JavaDoc[] {".php" }; }; } },
87         };
88     
89     private static final int defaultCPDMinimumLength = 75;
90     private static final Map JavaDoc langConfigsByLabel = new HashMap JavaDoc(languageSets.length);
91     private static final KeyStroke copy = KeyStroke.getKeyStroke(KeyEvent.VK_C,ActionEvent.CTRL_MASK,false);
92     private static final KeyStroke delete = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
93     
94     private class ColumnSpec {
95         private String JavaDoc label;
96         private int alignment;
97         private int width;
98         private Comparator JavaDoc sorter;
99         
100         public ColumnSpec(String JavaDoc aLabel, int anAlignment, int aWidth, Comparator JavaDoc aSorter) {
101             label = aLabel;
102             alignment = anAlignment;
103             width = aWidth;
104             sorter = aSorter;
105         }
106         public String JavaDoc label() { return label; };
107         public int alignment() { return alignment; };
108         public int width() { return width; };
109         public Comparator JavaDoc sorter() { return sorter; };
110     }
111
112     private final ColumnSpec[] matchColumns = new ColumnSpec[] {
113         new ColumnSpec("Source", SwingConstants.LEFT, -1, Match.LabelComparator),
114         new ColumnSpec("Matches", SwingConstants.RIGHT, 60, Match.MatchesComparator),
115         new ColumnSpec("Lines", SwingConstants.RIGHT, 45, Match.LinesComparator),
116         };
117     
118     static {
119         for (int i=0; i<languageSets.length; i++) {
120             langConfigsByLabel.put(languageSets[i][0], languageSets[i][1]);
121         }
122     }
123     
124     private static LanguageConfig languageConfigFor(String JavaDoc label) {
125         return (LanguageConfig)langConfigsByLabel.get(label);
126     }
127     
128     private static class CancelListener implements ActionListener JavaDoc {
129         public void actionPerformed(ActionEvent JavaDoc e) {
130             System.exit(0);
131         }
132     }
133
134     private class GoListener implements ActionListener JavaDoc {
135         public void actionPerformed(ActionEvent JavaDoc e) {
136             new Thread JavaDoc(new Runnable JavaDoc() {
137                 public void run() {
138                     tokenizingFilesBar.setValue(0);
139                     tokenizingFilesBar.setString("");
140                     resultsTextArea.setText("");
141                     phaseLabel.setText("");
142                     timeField.setText("");
143                     go();
144                 }
145             }).start();
146         }
147     }
148     
149     private class SaveListener implements ActionListener JavaDoc {
150         
151         final Renderer renderer;
152         
153         public SaveListener(Renderer theRenderer) {
154             renderer = theRenderer;
155         }
156         
157         public void actionPerformed(ActionEvent JavaDoc evt) {
158             JFileChooser fcSave = new JFileChooser();
159             int ret = fcSave.showSaveDialog(GUI.this.frame);
160             File JavaDoc f = fcSave.getSelectedFile();
161             if (f == null || ret != JFileChooser.APPROVE_OPTION) return;
162                         
163             if (!f.canWrite()) {
164                 PrintWriter JavaDoc pw = null;
165                 try {
166                     pw = new PrintWriter JavaDoc(new FileOutputStream JavaDoc(f));
167                     pw.write(renderer.render(matches.iterator()));
168                     pw.flush();
169                     JOptionPane.showMessageDialog(frame, "Saved " + matches.size() + " matches");
170                 } catch (IOException JavaDoc e) {
171                     error("Couldn't save file" + f.getAbsolutePath(), e);
172                 } finally {
173                     if (pw != null) pw.close();
174                 }
175             } else {
176                 error("Could not write to file " + f.getAbsolutePath(), null);
177             }
178         }
179
180         private void error(String JavaDoc message, Exception JavaDoc e) {
181             if (e != null) {
182                 e.printStackTrace();
183             }
184             JOptionPane.showMessageDialog(GUI.this.frame, message);
185         }
186
187     }
188
189     private class BrowseListener implements ActionListener JavaDoc {
190         public void actionPerformed(ActionEvent JavaDoc e) {
191             JFileChooser fc = new JFileChooser(rootDirectoryField.getText());
192             fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
193             fc.showDialog(frame, "Select");
194             if (fc.getSelectedFile() != null) {
195                 rootDirectoryField.setText(fc.getSelectedFile().getAbsolutePath());
196             }
197         }
198     }
199     
200     private class AlignmentRenderer extends DefaultTableCellRenderer JavaDoc {
201         
202         private int[] alignments;
203         
204         public AlignmentRenderer(int[] theAlignments) {
205             alignments = theAlignments;
206         };
207         
208         public Component JavaDoc getTableCellRendererComponent(JTable table, Object JavaDoc value, boolean isSelected, boolean hasFocus, int row, int column) {
209             super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
210  
211             setHorizontalAlignment(alignments[column]);
212  
213             return this;
214         }
215     }
216     
217     private JTextField rootDirectoryField = new JTextField(System.getProperty("user.home"));
218     private JTextField minimumLengthField = new JTextField(Integer.toString(defaultCPDMinimumLength));
219     private JTextField timeField = new JTextField(6);
220     private JLabel phaseLabel = new JLabel();
221     private JProgressBar tokenizingFilesBar = new JProgressBar();
222     private JTextArea resultsTextArea = new JTextArea();
223     private JCheckBox recurseCheckbox = new JCheckBox("", true);
224     private JCheckBox ignoreLiteralsCheckbox = new JCheckBox("", false);
225     private JComboBox languageBox = new JComboBox();
226     private JTextField extensionField = new JTextField();
227     private JLabel extensionLabel = new JLabel("Extension:", SwingConstants.RIGHT);
228     private JTable resultsTable = new JTable();
229     private JButton goButton;
230     private JButton cancelButton;
231     private JPanel progressPanel;
232     private JFrame frame;
233     private boolean trimLeadingWhitespace;
234
235     private List JavaDoc matches = new ArrayList JavaDoc();
236
237     private void addSaveOptionsTo(JMenu menu) {
238         
239         JMenuItem saveItem;
240         
241         for (int i=0; i<rendererSets.length; i++) {
242             saveItem = new JMenuItem("Save as " + rendererSets[i][0]);
243             saveItem.addActionListener(new SaveListener((Renderer)rendererSets[i][1]));
244             menu.add(saveItem);
245         }
246     }
247     
248     public GUI() {
249         frame = new JFrame("PMD Duplicate Code Detector");
250
251         timeField.setEditable(false);
252
253         JMenu fileMenu = new JMenu("File");
254         fileMenu.setMnemonic('f');
255         
256         addSaveOptionsTo(fileMenu);
257              
258         JMenuItem exitItem = new JMenuItem("Exit");
259         exitItem.setMnemonic('x');
260         exitItem.addActionListener(new CancelListener());
261         fileMenu.add(exitItem);
262         JMenu viewMenu = new JMenu("View");
263         fileMenu.setMnemonic('v');
264         JMenuItem trimItem = new JCheckBoxMenuItem("Trim leading whitespace");
265         trimItem.addItemListener(new ItemListener JavaDoc() {
266             public void itemStateChanged(ItemEvent JavaDoc e) {
267                 AbstractButton button = (AbstractButton)e.getItem();
268                 GUI.this.trimLeadingWhitespace = button.isSelected();
269             }
270         });
271         viewMenu.add(trimItem);
272         JMenuBar menuBar = new JMenuBar();
273         menuBar.add(fileMenu);
274         menuBar.add(viewMenu);
275         frame.setJMenuBar(menuBar);
276
277         // first make all the buttons
278
JButton browseButton = new JButton("Browse");
279         browseButton.setMnemonic('b');
280         browseButton.addActionListener(new BrowseListener());
281         goButton = new JButton("Go");
282         goButton.setMnemonic('g');
283         goButton.addActionListener(new GoListener());
284         cancelButton = new JButton("Cancel");
285         cancelButton.addActionListener(new CancelListener());
286
287         JPanel settingsPanel = makeSettingsPanel(browseButton, goButton, cancelButton);
288         progressPanel = makeProgressPanel();
289         JPanel resultsPanel = makeResultsPanel();
290
291         adjustLanguageControlsFor((LanguageConfig)languageSets[0][1]);
292         
293         frame.getContentPane().setLayout(new BorderLayout JavaDoc());
294         JPanel topPanel = new JPanel();
295         topPanel.setLayout(new BorderLayout JavaDoc());
296         topPanel.add(settingsPanel, BorderLayout.NORTH);
297         topPanel.add(progressPanel, BorderLayout.CENTER);
298         setProgressControls(false); // not running now
299
frame.getContentPane().add(topPanel, BorderLayout.NORTH);
300         frame.getContentPane().add(resultsPanel, BorderLayout.CENTER);
301         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
302         frame.pack();
303         frame.setVisible(true);
304     }
305
306     private void adjustLanguageControlsFor(LanguageConfig current) {
307          ignoreLiteralsCheckbox.setEnabled(current.ignoreLiteralsByDefault());
308          extensionField.setText(current.extensions()[0]);
309          boolean enableExtension = current.extensions()[0].length() == 0;
310          extensionField.setEnabled(enableExtension);
311          extensionLabel.setEnabled(enableExtension);
312     }
313     
314     private JPanel makeSettingsPanel(JButton browseButton, JButton goButton, JButton cxButton) {
315         JPanel settingsPanel = new JPanel();
316         GridBagHelper helper = new GridBagHelper(settingsPanel, new double[]{0.2, 0.7, 0.1, 0.1});
317         helper.addLabel("Root source directory:");
318         helper.add(rootDirectoryField);
319         helper.add(browseButton, 2);
320         helper.nextRow();
321         helper.addLabel("Report duplicate chunks larger than:");
322         minimumLengthField.setColumns(4);
323         helper.add(minimumLengthField);
324         helper.addLabel("Language:");
325         for (int i=0; i<languageSets.length; i++) {
326             languageBox.addItem(languageSets[i][0]);
327         }
328         languageBox.addActionListener(new ActionListener JavaDoc() {
329             public void actionPerformed(ActionEvent JavaDoc e) {
330                 adjustLanguageControlsFor(
331                         languageConfigFor((String JavaDoc)languageBox.getSelectedItem())
332                         );
333             }
334         });
335         helper.add(languageBox);
336         helper.nextRow();
337         helper.addLabel("Also scan subdirectories?");
338         helper.add(recurseCheckbox);
339
340         helper.add(extensionLabel);
341         helper.add(extensionField);
342
343         helper.nextRow();
344         helper.addLabel("Ignore literals and identifiers?");
345         helper.add(ignoreLiteralsCheckbox);
346         helper.add(goButton);
347         helper.add(cxButton);
348         helper.nextRow();
349 // settingsPanel.setBorder(BorderFactory.createTitledBorder("Settings"));
350
return settingsPanel;
351     }
352
353     private JPanel makeProgressPanel() {
354         JPanel progressPanel = new JPanel();
355         final double[] weights = {0.0, 0.8, 0.4, 0.2};
356         GridBagHelper helper = new GridBagHelper(progressPanel, weights);
357         helper.addLabel("Tokenizing files:");
358         helper.add(tokenizingFilesBar, 3);
359         helper.nextRow();
360         helper.addLabel("Phase:");
361         helper.add(phaseLabel);
362         helper.addLabel("Time elapsed:");
363         helper.add(timeField);
364         helper.nextRow();
365         progressPanel.setBorder(BorderFactory.createTitledBorder("Progress"));
366         return progressPanel;
367     }
368     
369     private JPanel makeResultsPanel() {
370         JPanel resultsPanel = new JPanel();
371         resultsPanel.setLayout(new BorderLayout JavaDoc());
372         JScrollPane areaScrollPane = new JScrollPane(resultsTextArea);
373         resultsTextArea.setEditable(false);
374         areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
375         areaScrollPane.setPreferredSize(new Dimension JavaDoc(600, 300));
376         
377         resultsPanel.add(makeMatchList(), BorderLayout.WEST);
378         resultsPanel.add(areaScrollPane, BorderLayout.CENTER);
379         return resultsPanel;
380     }
381
382     private void populateResultArea() {
383         int[] selectionIndices = resultsTable.getSelectedRows();
384         TableModel JavaDoc model = resultsTable.getModel();
385         List JavaDoc selections = new ArrayList JavaDoc(selectionIndices.length);
386         for (int i=0; i<selectionIndices.length; i++) {
387             selections.add(model.getValueAt(selectionIndices[i], 99));
388         }
389         String JavaDoc report = new SimpleRenderer(trimLeadingWhitespace).render(selections.iterator());
390         resultsTextArea.setText(report);
391         resultsTextArea.setCaretPosition(0); // move to the top
392
}
393         
394     private void copyMatchListSelectionsToClipboard() {
395         
396         int[] selectionIndices = resultsTable.getSelectedRows();
397         int colCount = resultsTable.getColumnCount();
398         
399         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
400                 
401         for (int r=0; r<selectionIndices.length; r++) {
402             if (r > 0) sb.append('\n');
403             sb.append(resultsTable.getValueAt(selectionIndices[r], 0));
404             for (int c=1; c<colCount; c++) {
405                 sb.append('\t');
406                 sb.append(resultsTable.getValueAt(selectionIndices[r], c));
407             }
408         }
409         
410         StringSelection JavaDoc ss = new StringSelection JavaDoc(sb.toString());
411         Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
412     }
413     
414     private void deleteMatchlistSelections() {
415         
416         int[] selectionIndices = resultsTable.getSelectedRows();
417         
418         for (int i=selectionIndices.length-1; i >=0; i--) {
419             matches.remove(selectionIndices[i]);
420         }
421         
422         resultsTable.getSelectionModel().clearSelection();
423         resultsTable.addNotify();
424     }
425     
426     private JComponent makeMatchList() {
427         
428         resultsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener JavaDoc() {
429             public void valueChanged(ListSelectionEvent JavaDoc e) {
430                 populateResultArea();
431             }});
432         
433         resultsTable.registerKeyboardAction(new ActionListener JavaDoc() {
434             public void actionPerformed(ActionEvent JavaDoc e) { copyMatchListSelectionsToClipboard(); }
435             },"Copy", copy, JComponent.WHEN_FOCUSED);
436         
437         resultsTable.registerKeyboardAction(new ActionListener JavaDoc() {
438             public void actionPerformed(ActionEvent JavaDoc e) { deleteMatchlistSelections(); }
439             },"Del", delete, JComponent.WHEN_FOCUSED);
440         
441         int[] alignments = new int[matchColumns.length];
442         for (int i=0; i<alignments.length; i++) alignments[i] = matchColumns[i].alignment();
443
444         resultsTable.setDefaultRenderer(Object JavaDoc.class, new AlignmentRenderer(alignments));
445         
446         final JTableHeader JavaDoc header = resultsTable.getTableHeader();
447         header.addMouseListener( new MouseAdapter JavaDoc() {
448             public void mouseClicked(MouseEvent JavaDoc e) {
449                 sortOnColumn(header.columnAtPoint(new Point JavaDoc(e.getX(), e.getY())));
450                 }
451             });
452         
453         return new JScrollPane(resultsTable);
454     }
455     
456     private boolean isLegalPath(String JavaDoc path, LanguageConfig config) {
457         String JavaDoc[] extensions = config.extensions();
458         for (int i=0; i<extensions.length; i++) {
459             if (path.endsWith(extensions[i]) && extensions[i].length() > 0) return true;
460         }
461         return false;
462     }
463     
464     private String JavaDoc setLabelFor(Match match) {
465         
466         Set JavaDoc sourceIDs = new HashSet JavaDoc(match.getMarkCount());
467         for (Iterator JavaDoc occurrences = match.iterator(); occurrences.hasNext();) {
468              sourceIDs.add( ((TokenEntry) occurrences.next()).getTokenSrcID());
469           }
470         String JavaDoc label;
471         
472         if (sourceIDs.size() == 1) {
473             String JavaDoc sourceId = (String JavaDoc)sourceIDs.iterator().next();
474             int separatorPos = sourceId.lastIndexOf(File.separatorChar);
475             label = "..." + sourceId.substring(separatorPos);
476             } else {
477                 label = "(" + sourceIDs.size() + " separate files)";
478             }
479             
480         match.setLabel(label);
481         return label;
482     }
483     
484     private void setProgressControls(boolean isRunning) {
485         progressPanel.setVisible(isRunning);
486         goButton.setEnabled(!isRunning);
487         cancelButton.setEnabled(isRunning);
488     }
489     
490     private void go() {
491         String JavaDoc dirPath = rootDirectoryField.getText();
492         try {
493             if (!(new File JavaDoc(dirPath)).exists()) {
494                 JOptionPane.showMessageDialog(frame,
495                         "Can't read from that root source directory",
496                         "Error", JOptionPane.ERROR_MESSAGE);
497                 return;
498             }
499       
500             setProgressControls(true);
501
502             Properties JavaDoc p = new Properties JavaDoc();
503             p.setProperty(JavaTokenizer.IGNORE_LITERALS, String.valueOf(ignoreLiteralsCheckbox.isSelected()));
504             p.setProperty(LanguageFactory.EXTENSION, extensionField.getText());
505             LanguageConfig conf = languageConfigFor((String JavaDoc)languageBox.getSelectedItem());
506             Language language = conf.languageFor(new LanguageFactory(), p);
507             CPD cpd = new CPD(Integer.parseInt(minimumLengthField.getText()), language);
508             cpd.setCpdListener(this);
509             tokenizingFilesBar.setMinimum(0);
510             phaseLabel.setText("");
511             if (isLegalPath(dirPath, conf)) { // should use the language file filter instead?
512
cpd.add(new File JavaDoc(dirPath));
513             } else {
514                 if (recurseCheckbox.isSelected()) {
515                     cpd.addRecursively(dirPath);
516                 } else {
517                     cpd.addAllInDirectory(dirPath);
518                 }
519             }
520             final long start = System.currentTimeMillis();
521             Timer t = new Timer(1000, new ActionListener JavaDoc() {
522                 public void actionPerformed(ActionEvent JavaDoc e) {
523                     long now = System.currentTimeMillis();
524                     long elapsedMillis = now - start;
525                     long elapsedSeconds = elapsedMillis / 1000;
526                     long minutes = (long) Math.floor(elapsedSeconds / 60);
527                     long seconds = elapsedSeconds - (minutes * 60);
528                     timeField.setText(""
529                             + munge(String.valueOf(minutes))
530                             + ':'
531                             + munge(String.valueOf(seconds)));
532                 }
533
534                 private String JavaDoc munge(String JavaDoc in) {
535                     if (in.length() < 2) {
536                         in = "0" + in;
537                     }
538                     return in;
539                 }
540             });
541             t.start();
542             cpd.go();
543             t.stop();
544             
545             matches = new ArrayList JavaDoc();
546             Match match;
547             for (Iterator JavaDoc i = cpd.getMatches(); i.hasNext();) {
548                 match = (Match)i.next();
549                 setLabelFor(match);
550                 matches.add(match);
551             }
552
553             String JavaDoc report = new SimpleRenderer().render(cpd.getMatches());
554             if (report.length() == 0) {
555                 JOptionPane.showMessageDialog(frame,
556                         "Done; couldn't find any duplicates longer than " + minimumLengthField.getText() + " tokens");
557             } else {
558                 resultsTextArea.setText(report);
559                 setListDataFrom(cpd.getMatches());
560                 
561             }
562         } catch (Throwable JavaDoc t) {
563             t.printStackTrace();
564             JOptionPane.showMessageDialog(frame, "Halted due to " + t.getClass().getName() + "; " + t.getMessage());
565         }
566         setProgressControls(false);
567     }
568     
569     private interface SortingTableModel extends TableModel JavaDoc {
570         public int sortColumn();
571         public void sortColumn(int column);
572         public boolean sortDescending();
573         public void sortDescending(boolean flag);
574         public void sort(Comparator JavaDoc comparator);
575     }
576     
577     private TableModel JavaDoc tableModelFrom(final List JavaDoc items) {
578         
579         TableModel JavaDoc model = new SortingTableModel() {
580             
581             private int sortColumn;
582             private boolean sortDescending;
583             
584              public Object JavaDoc getValueAt(int rowIndex, int columnIndex) {
585                 Match match = (Match) items.get(rowIndex);
586                 switch (columnIndex) {
587                     case 0: return match.getLabel();
588                     case 2: return Integer.toString(match.getLineCount());
589                     case 1: return match.getMarkCount() > 2 ? Integer.toString(match.getMarkCount()) : "";
590                     case 99: return match;
591                     }
592                 return "";
593                 }
594             public int getColumnCount() { return matchColumns.length; }
595             public int getRowCount() { return items.size(); }
596             public boolean isCellEditable(int rowIndex, int columnIndex) { return false; }
597             public Class JavaDoc getColumnClass(int columnIndex) { return Object JavaDoc.class; }
598             public void setValueAt(Object JavaDoc aValue, int rowIndex, int columnIndex) { }
599             public String JavaDoc getColumnName(int i) { return matchColumns[i].label(); }
600             public void addTableModelListener(TableModelListener JavaDoc l) { }
601             public void removeTableModelListener(TableModelListener JavaDoc l) { }
602             public int sortColumn() { return sortColumn; };
603             public void sortColumn(int column) { sortColumn = column; };
604             public boolean sortDescending() { return sortDescending; };
605             public void sortDescending(boolean flag) { sortDescending = flag; };
606             public void sort(Comparator JavaDoc comparator) {
607                 Collections.sort(items, comparator);
608                 if (sortDescending) Collections.reverse(items);
609                 }
610             };
611         
612         return model;
613     }
614         
615     private void sortOnColumn(int columnIndex) {
616         Comparator JavaDoc comparator = matchColumns[columnIndex].sorter();
617         SortingTableModel model = (SortingTableModel)resultsTable.getModel();
618         if (model.sortColumn() == columnIndex) {
619             model.sortDescending(!model.sortDescending());
620         }
621         model.sortColumn(columnIndex);
622         model.sort(comparator);
623         
624         resultsTable.getSelectionModel().clearSelection();
625         resultsTable.repaint();
626     }
627     
628     private void setListDataFrom(Iterator JavaDoc iter) {
629
630         resultsTable.setModel(tableModelFrom(matches));
631         
632         TableColumnModel JavaDoc colModel = resultsTable.getColumnModel();
633         TableColumn JavaDoc column;
634         int width;
635         
636         for (int i=0; i<matchColumns.length; i++) {
637             if (matchColumns[i].width() > 0) {
638                 column = colModel.getColumn(i);
639                 width = matchColumns[i].width();
640                 column.setPreferredWidth(width);
641                 column.setMinWidth(width);
642                 column.setMaxWidth(width);
643             }
644         }
645     }
646     
647     // CPDListener
648
public void phaseUpdate(int phase) {
649         phaseLabel.setText(getPhaseText(phase));
650     }
651
652     public String JavaDoc getPhaseText(int phase) {
653         switch (phase) {
654             case CPDListener.INIT:
655                 return "Initializing";
656             case CPDListener.HASH:
657                 return "Hashing";
658             case CPDListener.MATCH:
659                 return "Matching";
660             case CPDListener.GROUPING:
661                 return "Grouping";
662             case CPDListener.DONE:
663                 return "Done";
664             default :
665                 return "Unknown";
666         }
667     }
668
669     public void addedFile(int fileCount, File JavaDoc file) {
670         tokenizingFilesBar.setMaximum(fileCount);
671         tokenizingFilesBar.setValue(tokenizingFilesBar.getValue() + 1);
672     }
673     // CPDListener
674

675     
676     public static void main(String JavaDoc[] args) {
677         //this should prevent the disk not found popup
678
// System.setSecurityManager(null);
679
new GUI();
680     }
681
682 }
683
Popular Tags