KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > gui > FindBugsFrame


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2003-2005, University of Maryland
4  * Copyright (C) 2004 Dave Brosius <dbrosius@users.sourceforge.net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */

20
21 /*
22  * FindBugsFrame.java
23  *
24  * Created on March 30, 2003, 12:05 PM
25  */

26
27 package edu.umd.cs.findbugs.gui;
28
29 import java.awt.BorderLayout JavaDoc;
30 import java.awt.CardLayout JavaDoc;
31 import java.awt.Color JavaDoc;
32 import java.awt.Component JavaDoc;
33 import java.awt.Cursor JavaDoc;
34 import java.awt.Dimension JavaDoc;
35 import java.awt.Event JavaDoc;
36 import java.awt.Font JavaDoc;
37 import java.awt.Graphics JavaDoc;
38 import java.awt.HeadlessException JavaDoc;
39 import java.awt.Point JavaDoc;
40 import java.awt.Rectangle JavaDoc;
41 import java.awt.Shape JavaDoc;
42 import java.awt.Toolkit JavaDoc;
43 import java.awt.datatransfer.Clipboard JavaDoc;
44 import java.awt.datatransfer.DataFlavor JavaDoc;
45 import java.awt.datatransfer.StringSelection JavaDoc;
46 import java.awt.datatransfer.Transferable JavaDoc;
47 import java.awt.event.ActionEvent JavaDoc;
48 import java.awt.event.ActionListener JavaDoc;
49 import java.awt.event.KeyEvent JavaDoc;
50 import java.io.BufferedReader JavaDoc;
51 import java.io.File JavaDoc;
52 import java.io.IOException JavaDoc;
53 import java.io.InputStream JavaDoc;
54 import java.io.InputStreamReader JavaDoc;
55 import java.io.Serializable JavaDoc;
56 import java.io.StringReader JavaDoc;
57 import java.lang.reflect.Method JavaDoc;
58 import java.net.URL JavaDoc;
59 import java.text.MessageFormat JavaDoc;
60 import java.util.Arrays JavaDoc;
61 import java.util.Collection JavaDoc;
62 import java.util.Comparator JavaDoc;
63 import java.util.HashSet JavaDoc;
64 import java.util.Iterator JavaDoc;
65 import java.util.List JavaDoc;
66 import java.util.TreeSet JavaDoc;
67
68 import javax.swing.AbstractButton JavaDoc;
69 import javax.swing.ButtonGroup JavaDoc;
70 import javax.swing.DefaultListModel JavaDoc;
71 import javax.swing.ImageIcon JavaDoc;
72 import javax.swing.JCheckBoxMenuItem JavaDoc;
73 import javax.swing.JComponent JavaDoc;
74 import javax.swing.JDialog JavaDoc;
75 import javax.swing.JFileChooser JavaDoc;
76 import javax.swing.JList JavaDoc;
77 import javax.swing.JMenuItem JavaDoc;
78 import javax.swing.JOptionPane JavaDoc;
79 import javax.swing.JRadioButton JavaDoc;
80 import javax.swing.JScrollPane JavaDoc;
81 import javax.swing.JSplitPane JavaDoc;
82 import javax.swing.JTextField JavaDoc;
83 import javax.swing.JTree JavaDoc;
84 import javax.swing.JViewport JavaDoc;
85 import javax.swing.KeyStroke JavaDoc;
86 import javax.swing.ListModel JavaDoc;
87 import javax.swing.SwingUtilities JavaDoc;
88 import javax.swing.UIManager JavaDoc;
89 import javax.swing.event.TreeSelectionEvent JavaDoc;
90 import javax.swing.event.TreeSelectionListener JavaDoc;
91 import javax.swing.filechooser.FileFilter JavaDoc;
92 import javax.swing.text.BadLocationException JavaDoc;
93 import javax.swing.text.DefaultHighlighter JavaDoc;
94 import javax.swing.text.Highlighter JavaDoc;
95 import javax.swing.text.JTextComponent JavaDoc;
96 import javax.swing.text.Position JavaDoc;
97 import javax.swing.text.View JavaDoc;
98 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
99 import javax.swing.tree.DefaultTreeModel JavaDoc;
100 import javax.swing.tree.TreePath JavaDoc;
101 import javax.swing.tree.TreeSelectionModel JavaDoc;
102
103 import org.dom4j.DocumentException;
104
105 import edu.umd.cs.findbugs.BugAnnotation;
106 import edu.umd.cs.findbugs.BugInstance;
107 import edu.umd.cs.findbugs.BugPattern;
108 import edu.umd.cs.findbugs.Detector;
109 import edu.umd.cs.findbugs.DetectorFactoryCollection;
110 import edu.umd.cs.findbugs.FindBugs;
111 import edu.umd.cs.findbugs.FindBugsCommandLine;
112 import edu.umd.cs.findbugs.I18N;
113 import edu.umd.cs.findbugs.L10N;
114 import edu.umd.cs.findbugs.MethodAnnotation;
115 import edu.umd.cs.findbugs.Project;
116 import edu.umd.cs.findbugs.ShowHelp;
117 import edu.umd.cs.findbugs.SourceLineAnnotation;
118 import edu.umd.cs.findbugs.SystemProperties;
119 import edu.umd.cs.findbugs.annotations.SuppressWarnings;
120 import edu.umd.cs.findbugs.ba.SourceFile;
121 import edu.umd.cs.findbugs.ba.SourceFinder;
122 import edu.umd.cs.findbugs.config.AnalysisFeatureSetting;
123 import edu.umd.cs.findbugs.config.ProjectFilterSettings;
124 import edu.umd.cs.findbugs.config.UserPreferences;
125 import edu.umd.cs.findbugs.config.CommandLine.HelpRequestedException;
126
127 /**
128  * The main GUI frame for FindBugs.
129  *
130  * @author David Hovemeyer
131  */

132 public final class FindBugsFrame extends javax.swing.JFrame JavaDoc implements LogSync {
133     /**
134      *
135      */

136     private static final int fontSize = 12;
137     /**
138      *
139      */

140     private static final Font JavaDoc SOURCE_FONT = new java.awt.Font JavaDoc("Monospaced", 0, fontSize);
141     private static final Font JavaDoc JTREE_FONT = new java.awt.Font JavaDoc("SansSerif", 0, fontSize);
142
143     /**
144      *
145      */

146     private static final Font JavaDoc LABEL_FONT = new java.awt.Font JavaDoc("Dialog", 1, 2*fontSize);
147
148     /**
149      *
150      */

151     private static final Font JavaDoc BUTTON_FONT = new java.awt.Font JavaDoc("Dialog", 0, fontSize);
152
153     private static final long serialVersionUID = 1L;
154
155     /* ----------------------------------------------------------------------
156      * Helper classes
157      * ---------------------------------------------------------------------- */

158     static final Color JavaDoc HIGH_PRIORITY_COLOR = new Color JavaDoc(0xff0000);
159     static final Color JavaDoc NORMAL_PRIORITY_COLOR = new Color JavaDoc(0x9f0000);
160     static final Color JavaDoc LOW_PRIORITY_COLOR = Color.BLACK;
161     static final Color JavaDoc EXP_PRIORITY_COLOR = Color.BLACK;
162
163     /**
164      * Tree node type for BugInstances.
165      * We use this instead of plain DefaultMutableTreeNodes in order to
166      * get more control over the exact text that is shown in the tree.
167      */

168     private class BugTreeNode extends DefaultMutableTreeNode JavaDoc {
169         private static final long serialVersionUID = 1L;
170         private int count;
171
172         public BugTreeNode(BugInstance bugInstance) {
173             super(bugInstance);
174             count = -1;
175         }
176
177         public void setCount(int count) {
178             this.count = count;
179         }
180
181         @Override JavaDoc
182         public String JavaDoc toString() {
183             try {
184                 BugInstance bugInstance = (BugInstance) getUserObject();
185                 StringBuffer JavaDoc result = new StringBuffer JavaDoc();
186
187                 if (count >= 0) {
188                     result.append(count);
189                     result.append(": ");
190                 }
191
192                 if (bugInstance.isExperimental())
193                     result.append(L10N.getLocalString("msg.exp_txt", "EXP: "));
194
195                 result.append(fullDescriptionsItem.isSelected() ? bugInstance.getMessage() : bugInstance.toString());
196
197                 return result.toString();
198             } catch (Exception JavaDoc e) {
199                 return MessageFormat.format(L10N.getLocalString("msg.errorformatting_txt", "Error formatting message for bug: "), new Object JavaDoc[]{e.toString()});
200             }
201         }
202     }
203
204     /**
205      * Compare BugInstance class names.
206      * This is useful for grouping bug instances by class.
207      * Note that all instances with the same class name will compare
208      * as equal.
209      */

210     private static class BugInstanceClassComparator implements Comparator JavaDoc<BugInstance> {
211         public int compare(BugInstance lhs, BugInstance rhs) {
212             return lhs.getPrimaryClass().compareTo(rhs.getPrimaryClass());
213         }
214     }
215
216     /**
217      * The instance of BugInstanceClassComparator.
218      */

219     private static final Comparator JavaDoc<BugInstance> bugInstanceClassComparator = new BugInstanceClassComparator();
220
221     /**
222      * Compare BugInstance package names.
223      * This is useful for grouping bug instances by package.
224      * Note that all instances with the same package name will compare
225      * as equal.
226      */

227     private static class BugInstancePackageComparator implements Comparator JavaDoc<BugInstance>, Serializable JavaDoc {
228         private static final long serialVersionUID = 1L;
229         public int compare(BugInstance lhs, BugInstance rhs) {
230             return lhs.getPrimaryClass().getPackageName().compareTo(rhs.getPrimaryClass().getPackageName());
231         }
232     }
233
234     /**
235      * The instance of BugInstancePackageComparator.
236      */

237     private static final Comparator JavaDoc<BugInstance> bugInstancePackageComparator = new BugInstancePackageComparator();
238
239     /**
240      * Compare BugInstance bug types.
241      * This is useful for grouping bug instances by bug type.
242      * Note that all instances with the same bug type will compare
243      * as equal.
244      */

245     private static class BugInstanceTypeComparator implements Comparator JavaDoc<BugInstance>, Serializable JavaDoc {
246         private static final long serialVersionUID = 1L;
247         public int compare(BugInstance lhs, BugInstance rhs) {
248             String JavaDoc lhsString = lhs.toString();
249             String JavaDoc rhsString = rhs.toString();
250             return lhsString.substring(0, lhsString.indexOf(':')).compareTo(rhsString.substring(0, rhsString.indexOf(':')));
251         }
252     }
253
254     /**
255      * The instance of BugInstanceTypeComparator.
256      */

257     private static final Comparator JavaDoc<BugInstance> bugInstanceTypeComparator = new BugInstanceTypeComparator();
258
259     /**
260      * Compare BugInstance bug categories.
261      * This is useful for grouping bug instances by bug category.
262      * Note that all instances with the same bug category will compare
263      * as equal.
264      */

265     private static class BugInstanceCategoryComparator implements Comparator JavaDoc<BugInstance>, Serializable JavaDoc {
266         private static final long serialVersionUID = 1L;
267
268         public int compare(BugInstance lhs, BugInstance rhs) {
269             return getCategory(lhs).compareTo(getCategory(rhs));
270         }
271
272         private String JavaDoc getCategory(BugInstance warning) {
273             BugPattern bugPattern = warning.getBugPattern();
274             if (bugPattern == null) {
275                 if (FindBugs.DEBUG)
276                     System.out.println("Unknown bug pattern for bug type: " + warning.getType());
277                 return "";
278             } else {
279                 return bugPattern.getCategory();
280             }
281         }
282     }
283
284     /**
285      * The instance of BugInstanceCategoryComparator.
286      */

287     private static final Comparator JavaDoc<BugInstance> bugInstanceCategoryComparator = new BugInstanceCategoryComparator();
288
289         /**
290      * Two-level comparison of bug instances by class name and
291      * BugInstance natural ordering.
292      */

293     private static class BugInstanceByClassComparator implements Comparator JavaDoc<BugInstance>, Serializable JavaDoc {
294         private static final long serialVersionUID = 1L;
295         public int compare(BugInstance a, BugInstance b) {
296             int cmp = bugInstanceClassComparator.compare(a, b);
297             if (cmp != 0)
298                 return cmp;
299             return a.compareTo(b);
300         }
301     }
302
303     /**
304      * The instance of BugInstanceByClassComparator.
305      */

306     private static final Comparator JavaDoc<BugInstance> bugInstanceByClassComparator = new FindBugsFrame.BugInstanceByClassComparator();
307
308     /**
309      * Two-level comparison of bug instances by package and
310      * BugInstance natural ordering.
311      */

312     private static class BugInstanceByPackageComparator implements Comparator JavaDoc<BugInstance> {
313         public int compare(BugInstance a, BugInstance b) {
314             int cmp = bugInstancePackageComparator.compare(a, b);
315             if (cmp != 0)
316                 return cmp;
317             return a.compareTo(b);
318         }
319     }
320
321     /**
322      * The instance of BugInstanceByPackageComparator.
323      */

324     private static final Comparator JavaDoc<BugInstance> bugInstanceByPackageComparator = new FindBugsFrame.BugInstanceByPackageComparator();
325
326     /**
327      * Two-level comparison of bug instances by bug type and
328      * BugInstance natural ordering.
329      */

330     private static class BugInstanceByTypeComparator implements Comparator JavaDoc<BugInstance>, Serializable JavaDoc {
331         private static final long serialVersionUID = 1L;
332         public int compare(BugInstance a, BugInstance b) {
333             int cmp = bugInstanceTypeComparator.compare(a, b);
334             if (cmp != 0)
335                 return cmp;
336             return a.compareTo(b);
337         }
338     }
339         
340         /**
341      * The instance of BugTypeByTypeComparator.
342      */

343     private static final Comparator JavaDoc<BugInstance> bugInstanceByTypeComparator = new FindBugsFrame.BugInstanceByTypeComparator();
344
345     /**
346      * Two-level comparison of bug instances by bug category and
347      * BugInstance natural ordering.
348      */

349     private static class BugInstanceByCategoryComparator implements Comparator JavaDoc<BugInstance>, Serializable JavaDoc {
350         private static final long serialVersionUID = 1L;
351         public int compare(BugInstance a, BugInstance b) {
352             int cmp = bugInstanceCategoryComparator.compare(a, b);
353             if (cmp != 0)
354                 return cmp;
355             return a.compareTo(b);
356         }
357     }
358
359          /**
360      * The instance of BugTypeByCategoryComparator.
361      */

362     private static final Comparator JavaDoc<BugInstance> bugInstanceByCategoryComparator = new FindBugsFrame.BugInstanceByCategoryComparator();
363
364         /**
365      * Swing FileFilter class for file selection dialogs for FindBugs project files.
366      */

367     private static class ProjectFileFilter extends FileFilter JavaDoc {
368         @Override JavaDoc
369         public boolean accept(File JavaDoc file) {
370             return file.isDirectory() || file.getName().endsWith(".fb");
371         }
372
373         @Override JavaDoc
374         public String JavaDoc getDescription() {
375             return L10N.getLocalString("dlg.findbugsprojects_lbl", "FindBugs projects (*.fb)");
376         }
377     }
378
379         /**
380      * The instance of ProjectFileFilter.
381      */

382     private static final FileFilter JavaDoc projectFileFilter = new ProjectFileFilter();
383
384     /**
385      * Swing FileFilter for choosing an auxiliary classpath entry.
386      * Both Jar files and directories can be chosen.
387      */

388     private static class AuxClasspathEntryFileFilter extends FileFilter JavaDoc {
389         @Override JavaDoc
390         public boolean accept(File JavaDoc file) {
391             return file.isDirectory() || file.getName().endsWith(".jar");
392         }
393
394         @Override JavaDoc
395         public String JavaDoc getDescription() {
396             return L10N.getLocalString("dlg.jarsanddirectories_lbl", "Jar files and directories");
397         }
398     }
399
400     /**
401      * The instance of AuxClasspathEntryFileFilter.
402      */

403     private static final FileFilter JavaDoc auxClasspathEntryFileFilter = new AuxClasspathEntryFileFilter();
404
405     /**
406      * Swing FileFilter for choosing XML saved bug files.
407      */

408     private static class XMLFileFilter extends FileFilter JavaDoc {
409         @Override JavaDoc
410         public boolean accept(File JavaDoc file) {
411             return file.isDirectory() || file.getName().endsWith(".xml");
412         }
413
414         @Override JavaDoc
415         public String JavaDoc getDescription() {
416             return L10N.getLocalString("dlg.xmlsavedbugs_lbl", "XML saved bug files");
417         }
418     }
419
420     /**
421      * The instance of XMLFileFilter.
422      */

423     private static final FileFilter JavaDoc xmlFileFilter = new XMLFileFilter();
424
425     /**
426      * Set of archive file extensions.
427      */

428     private static final HashSet JavaDoc<String JavaDoc> archiveExtensionSet = new HashSet JavaDoc<String JavaDoc>();
429
430     static {
431         archiveExtensionSet.add(".jar");
432         archiveExtensionSet.add(".zip");
433         archiveExtensionSet.add(".ear");
434         archiveExtensionSet.add(".war");
435     }
436
437     /**
438      * File filter for choosing archives and directories.
439      */

440     private static class ArchiveAndDirectoryFilter extends FileFilter JavaDoc {
441         @Override JavaDoc
442         public boolean accept(File JavaDoc file) {
443             if (file.isDirectory())
444                 return true;
445
446             String JavaDoc fileName = file.getName();
447             int dot = fileName.lastIndexOf('.');
448             if (dot < 0)
449                 return false;
450             String JavaDoc extension = fileName.substring(dot);
451             return archiveExtensionSet.contains(extension);
452         }
453
454         @Override JavaDoc
455         public String JavaDoc getDescription() {
456             return L10N.getLocalString("dlg.javaarchives_lbl", "Java archives (*.jar,*.zip,*.ear,*.war)");
457         }
458     }
459
460     /**
461      * The instance of ArchiveAndDirectoryFilter.
462      */

463     private static final FileFilter JavaDoc archiveAndDirectoryFilter = new ArchiveAndDirectoryFilter();
464
465     /* ----------------------------------------------------------------------
466      * Constants
467      * ---------------------------------------------------------------------- */

468
469     static final String JavaDoc GROUP_BY_CLASS = "By class";
470     static final String JavaDoc GROUP_BY_PACKAGE = "By package";
471     static final String JavaDoc GROUP_BY_BUG_TYPE = "By bug type";
472         static final String JavaDoc GROUP_BY_BUG_CATEGORY="By bug category";
473     private static final String JavaDoc[] GROUP_BY_ORDER_LIST = {
474         GROUP_BY_CLASS, GROUP_BY_PACKAGE, GROUP_BY_BUG_TYPE, GROUP_BY_BUG_CATEGORY
475     };
476
477     /**
478      * A fudge value required in our hack to get the REAL maximum
479      * divider location for a JSplitPane. Experience suggests that
480      * the value "1" would work here, but setting it a little higher
481      * makes the code a bit more robust.
482      */

483     private static final int DIVIDER_FUDGE = 3;
484
485     private static final boolean BUG_COUNT = SystemProperties.getBoolean("findbugs.gui.bugCount");
486
487     /* ----------------------------------------------------------------------
488      * Member fields
489      * ---------------------------------------------------------------------- */

490     Component JavaDoc selectedComponent = null;
491     
492     /* ----------------------------------------------------------------------
493      * Constructor
494      * ---------------------------------------------------------------------- */

495     
496     /**
497      * Creates new form FindBugsFrame.
498      */

499     public FindBugsFrame() {
500         
501         UserPreferences prefs = UserPreferences.getUserPreferences();
502         prefs.read();
503         
504         String JavaDoc dirProp = SystemProperties.getProperty("user.dir");
505         
506         if (dirProp != null) {
507             currentDirectory = new File JavaDoc(dirProp);
508         }
509
510         initComponents();
511         postInitComponents();
512     }
513     
514     /* ----------------------------------------------------------------------
515      * Component initialization and event handlers
516      * ---------------------------------------------------------------------- */

517     
518     /**
519      * This method is called from within the constructor to
520      * initialize the form.
521      * WARNING: Do NOT modify this code. The content of this method is
522      * always regenerated by the Form Editor.
523      */

524     private void initComponents() {//GEN-BEGIN:initComponents
525
java.awt.GridBagConstraints JavaDoc gridBagConstraints;
526
527         priorityButtonGroup = new javax.swing.ButtonGroup JavaDoc();
528         effortButtonGroup = new javax.swing.ButtonGroup JavaDoc();
529         //consoleSplitter = new javax.swing.JSplitPane();
530
viewPanel = new javax.swing.JPanel JavaDoc();
531         emptyPanel = new javax.swing.JPanel JavaDoc();
532         reportPanel = new javax.swing.JPanel JavaDoc();
533         editProjectPanel = new javax.swing.JPanel JavaDoc();
534         jarFileLabel = new javax.swing.JLabel JavaDoc();
535         jarNameTextField = new javax.swing.JTextField JavaDoc();
536         addJarButton = new javax.swing.JButton JavaDoc();
537         jarFileListLabel = new javax.swing.JLabel JavaDoc();
538         sourceDirLabel = new javax.swing.JLabel JavaDoc();
539         srcDirTextField = new javax.swing.JTextField JavaDoc();
540         addSourceDirButton = new javax.swing.JButton JavaDoc();
541         sourceDirListLabel = new javax.swing.JLabel JavaDoc();
542         removeJarButton = new javax.swing.JButton JavaDoc();
543         removeSrcDirButton = new javax.swing.JButton JavaDoc();
544         jSeparator1 = new javax.swing.JSeparator JavaDoc();
545         browseJarButton = new javax.swing.JButton JavaDoc();
546         browseSrcDirButton = new javax.swing.JButton JavaDoc();
547         editProjectLabel = new javax.swing.JLabel JavaDoc();
548         jSeparator2 = new javax.swing.JSeparator JavaDoc();
549         findBugsButton = new javax.swing.JButton JavaDoc();
550         jSeparator4 = new javax.swing.JSeparator JavaDoc();
551         jarFileListScrollPane = new javax.swing.JScrollPane JavaDoc();
552         jarFileList = new javax.swing.JList JavaDoc();
553         sourceDirListScrollPane = new javax.swing.JScrollPane JavaDoc();
554         sourceDirList = new javax.swing.JList JavaDoc();
555         classpathEntryLabel = new javax.swing.JLabel JavaDoc();
556         classpathEntryListLabel = new javax.swing.JLabel JavaDoc();
557         classpathEntryTextField = new javax.swing.JTextField JavaDoc();
558         browseClasspathEntryButton = new javax.swing.JButton JavaDoc();
559         addClasspathEntryButton = new javax.swing.JButton JavaDoc();
560         removeClasspathEntryButton = new javax.swing.JButton JavaDoc();
561         classpathEntryListScrollPane = new javax.swing.JScrollPane JavaDoc();
562         classpathEntryList = new javax.swing.JList JavaDoc();
563         jSeparator5 = new javax.swing.JSeparator JavaDoc();
564         sourceUpButton = new javax.swing.JButton JavaDoc();
565         sourceDownButton = new javax.swing.JButton JavaDoc();
566         classpathUpButton = new javax.swing.JButton JavaDoc();
567         classpathDownButton = new javax.swing.JButton JavaDoc();
568         bugTreePanel = new javax.swing.JPanel JavaDoc();
569         bugTreeBugDetailsSplitter = new javax.swing.JSplitPane JavaDoc();
570         groupByTabbedPane = new javax.swing.JTabbedPane JavaDoc();
571         byClassScrollPane = new javax.swing.JScrollPane JavaDoc();
572         byClassBugTree = new javax.swing.JTree JavaDoc();
573         byClassBugTree.setFont(JTREE_FONT);
574         byPackageScrollPane = new javax.swing.JScrollPane JavaDoc();
575         byPackageBugTree = new javax.swing.JTree JavaDoc();
576         byPackageBugTree.setFont(JTREE_FONT);
577         byBugTypeScrollPane = new javax.swing.JScrollPane JavaDoc();
578         byBugTypeBugTree = new javax.swing.JTree JavaDoc();
579         byBugTypeBugTree.setFont(JTREE_FONT);
580         byBugCategoryScrollPane = new javax.swing.JScrollPane JavaDoc();
581         byBugCategoryBugTree = new javax.swing.JTree JavaDoc();
582         byBugCategoryBugTree.setFont(JTREE_FONT);
583         bySummary = new javax.swing.JScrollPane JavaDoc();
584         bugSummaryEditorPane = new javax.swing.JEditorPane JavaDoc();
585         bugDetailsTabbedPane = new javax.swing.JTabbedPane JavaDoc();
586         bugDescriptionScrollPane = new javax.swing.JScrollPane JavaDoc();
587         bugDescriptionEditorPane = new javax.swing.JEditorPane JavaDoc();
588         sourceTextAreaScrollPane = new javax.swing.JScrollPane JavaDoc();
589         sourceTextArea = new javax.swing.JTextArea JavaDoc();
590         annotationTextAreaScrollPane = new javax.swing.JScrollPane JavaDoc();
591         annotationTextArea = new javax.swing.JTextArea JavaDoc();
592         urlLabel = new javax.swing.JLabel JavaDoc();
593         jPanel1 = new javax.swing.JPanel JavaDoc();
594         logoLabel = new javax.swing.JLabel JavaDoc();
595         growBoxSpacer = new javax.swing.JLabel JavaDoc();
596         theMenuBar = new javax.swing.JMenuBar JavaDoc();
597         fileMenu = new javax.swing.JMenu JavaDoc();
598         newProjectItem = new javax.swing.JMenuItem JavaDoc();
599         openProjectItem = new javax.swing.JMenuItem JavaDoc();
600         recentProjectsMenu = new javax.swing.JMenu JavaDoc();
601         jSeparator9 = new javax.swing.JSeparator JavaDoc();
602         closeProjectItem = new javax.swing.JMenuItem JavaDoc();
603         saveProjectItem = new javax.swing.JMenuItem JavaDoc();
604         saveProjectAsItem = new javax.swing.JMenuItem JavaDoc();
605         reloadProjectItem = new javax.swing.JMenuItem JavaDoc();
606         jSeparator3 = new javax.swing.JSeparator JavaDoc();
607         loadBugsItem = new javax.swing.JMenuItem JavaDoc();
608         saveBugsItem = new javax.swing.JMenuItem JavaDoc();
609         jSeparator6 = new javax.swing.JSeparator JavaDoc();
610         exitItem = new javax.swing.JMenuItem JavaDoc();
611         editMenu = new javax.swing.JMenu JavaDoc();
612         cutItem = new javax.swing.JMenuItem JavaDoc();
613         copyItem = new javax.swing.JMenuItem JavaDoc();
614         pasteItem = new javax.swing.JMenuItem JavaDoc();
615         jSeparator10 = new javax.swing.JSeparator JavaDoc();
616         selectAllItem = new javax.swing.JMenuItem JavaDoc();
617         viewMenu = new javax.swing.JMenu JavaDoc();
618         viewBugDetailsItem = new javax.swing.JCheckBoxMenuItem JavaDoc();
619         fullDescriptionsItem = new javax.swing.JCheckBoxMenuItem JavaDoc();
620         jSeparator7 = new javax.swing.JSeparator JavaDoc();
621         filterWarningsMenu = new javax.swing.JMenu JavaDoc();
622         expPriorityButton = new javax.swing.JRadioButtonMenuItem JavaDoc();
623         lowPriorityButton = new javax.swing.JRadioButtonMenuItem JavaDoc();
624         mediumPriorityButton = new javax.swing.JRadioButtonMenuItem JavaDoc();
625         highPriorityButton = new javax.swing.JRadioButtonMenuItem JavaDoc();
626         jSeparator11 = new javax.swing.JSeparator JavaDoc();
627         jSeparator8 = new javax.swing.JSeparator JavaDoc();
628         viewProjectItem = new javax.swing.JRadioButtonMenuItem JavaDoc();
629         viewBugsItem = new javax.swing.JRadioButtonMenuItem JavaDoc();
630         settingsMenu = new javax.swing.JMenu JavaDoc();
631         configureDetectorsItem = new javax.swing.JMenuItem JavaDoc();
632         effortMenu = new javax.swing.JMenu JavaDoc();
633         minEffortItem = new javax.swing.JCheckBoxMenuItem JavaDoc();
634         normalEffortItem = new javax.swing.JCheckBoxMenuItem JavaDoc();
635         maxEffortItem = new javax.swing.JCheckBoxMenuItem JavaDoc();
636         helpMenu = new javax.swing.JMenu JavaDoc();
637         aboutItem = new javax.swing.JMenuItem JavaDoc();
638
639         getContentPane().setLayout(new java.awt.GridBagLayout JavaDoc());
640
641         addWindowListener(new java.awt.event.WindowAdapter JavaDoc() {
642             @Override JavaDoc
643             public void windowClosing(java.awt.event.WindowEvent JavaDoc evt) {
644                 exitForm(evt);
645             }
646             @Override JavaDoc
647             public void windowOpened(java.awt.event.WindowEvent JavaDoc evt) {
648                 formWindowOpened(evt);
649             }
650         });
651
652         viewPanel.setLayout(new java.awt.CardLayout JavaDoc());
653
654         viewPanel.add(emptyPanel, "EmptyPanel");
655
656         viewPanel.add(reportPanel, "ReportPanel");
657
658         editProjectPanel.setLayout(new java.awt.GridBagLayout JavaDoc());
659
660         jarFileLabel.setFont(BUTTON_FONT);
661         jarFileLabel.setText("Archive or directory:");
662         jarFileLabel.setText(L10N.getLocalString("dlg.jarfile_lbl", "Archive or Directory:"));
663         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
664         gridBagConstraints.gridx = 0;
665         gridBagConstraints.gridy = 2;
666         gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
667         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
668         editProjectPanel.add(jarFileLabel, gridBagConstraints);
669
670         jarNameTextField.addActionListener(new java.awt.event.ActionListener JavaDoc() {
671             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
672                 jarNameTextFieldActionPerformed(evt);
673             }
674         });
675         jarNameTextField.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
676             @Override JavaDoc
677             public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
678                 focusGainedHandler(evt);
679             }
680         });
681
682         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
683         gridBagConstraints.gridx = 1;
684         gridBagConstraints.gridy = 2;
685         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
686         gridBagConstraints.weightx = 1.0;
687         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 0);
688         editProjectPanel.add(jarNameTextField, gridBagConstraints);
689
690         addJarButton.setFont(BUTTON_FONT);
691         addJarButton.setText("Add");
692         addJarButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
693         addJarButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
694         addJarButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
695         addJarButton.setText(L10N.getLocalString("dlg.add_btn", "Add"));
696         addJarButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
697             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
698                 addJarButtonActionPerformed(evt);
699             }
700         });
701
702         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
703         gridBagConstraints.gridx = 3;
704         gridBagConstraints.gridy = 2;
705         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
706         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
707         editProjectPanel.add(addJarButton, gridBagConstraints);
708
709         jarFileListLabel.setFont(BUTTON_FONT);
710         jarFileListLabel.setText("Archives/directories:");
711         jarFileListLabel.setText(L10N.getLocalString("dlg.jarlist_lbl", "Archives/Directories:"));
712         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
713         gridBagConstraints.gridx = 0;
714         gridBagConstraints.gridy = 3;
715         gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
716         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
717         editProjectPanel.add(jarFileListLabel, gridBagConstraints);
718
719         sourceDirLabel.setFont(BUTTON_FONT);
720         sourceDirLabel.setText("Source directory:");
721         sourceDirLabel.setText(L10N.getLocalString("dlg.srcfile_lbl", "Source directory:"));
722         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
723         gridBagConstraints.gridx = 0;
724         gridBagConstraints.gridy = 8;
725         gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
726         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
727         editProjectPanel.add(sourceDirLabel, gridBagConstraints);
728
729         srcDirTextField.addActionListener(new java.awt.event.ActionListener JavaDoc() {
730             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
731                 srcDirTextFieldActionPerformed(evt);
732             }
733         });
734         srcDirTextField.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
735             @Override JavaDoc
736             public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
737                 focusGainedHandler(evt);
738             }
739         });
740
741         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
742         gridBagConstraints.gridx = 1;
743         gridBagConstraints.gridy = 8;
744         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
745         gridBagConstraints.weightx = 1.0;
746         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 0);
747         editProjectPanel.add(srcDirTextField, gridBagConstraints);
748
749         addSourceDirButton.setFont(BUTTON_FONT);
750         addSourceDirButton.setText("Add");
751         addSourceDirButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
752         addSourceDirButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
753         addSourceDirButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
754         addSourceDirButton.setText(L10N.getLocalString("dlg.add_btn", "Add"));
755         addSourceDirButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
756             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
757                 addSourceDirButtonActionPerformed(evt);
758             }
759         });
760
761         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
762         gridBagConstraints.gridx = 3;
763         gridBagConstraints.gridy = 8;
764         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
765         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
766         editProjectPanel.add(addSourceDirButton, gridBagConstraints);
767
768         sourceDirListLabel.setFont(BUTTON_FONT);
769         sourceDirListLabel.setText("Source directories:");
770         sourceDirListLabel.setText(L10N.getLocalString("dlg.srclist_lbl", "Source directories:"));
771         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
772         gridBagConstraints.gridx = 0;
773         gridBagConstraints.gridy = 9;
774         gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
775         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
776         editProjectPanel.add(sourceDirListLabel, gridBagConstraints);
777
778         removeJarButton.setFont(BUTTON_FONT);
779         removeJarButton.setText("Remove");
780         removeJarButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
781         removeJarButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
782         removeJarButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
783         removeJarButton.setText(L10N.getLocalString("dlg.remove_btn", "Remove"));
784         removeJarButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
785             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
786                 removeJarButtonActionPerformed(evt);
787             }
788         });
789
790         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
791         gridBagConstraints.gridx = 3;
792         gridBagConstraints.gridy = 3;
793         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
794         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
795         editProjectPanel.add(removeJarButton, gridBagConstraints);
796
797         removeSrcDirButton.setFont(BUTTON_FONT);
798         removeSrcDirButton.setText("Remove");
799         removeSrcDirButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
800         removeSrcDirButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
801         removeSrcDirButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
802         removeSrcDirButton.setText(L10N.getLocalString("dlg.remove_btn", "Remove"));
803         removeSrcDirButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
804             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
805                 removeSrcDirButtonActionPerformed(evt);
806             }
807         });
808
809         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
810         gridBagConstraints.gridx = 3;
811         gridBagConstraints.gridy = 9;
812         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
813         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
814         editProjectPanel.add(removeSrcDirButton, gridBagConstraints);
815
816         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
817         gridBagConstraints.gridx = 0;
818         gridBagConstraints.gridy = 1;
819         gridBagConstraints.gridwidth = 4;
820         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
821         gridBagConstraints.insets = new java.awt.Insets JavaDoc(3, 3, 3, 3);
822         editProjectPanel.add(jSeparator1, gridBagConstraints);
823
824         browseJarButton.setFont(BUTTON_FONT);
825         browseJarButton.setText("Browse");
826         browseJarButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
827         browseJarButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
828         browseJarButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
829         browseJarButton.setText(L10N.getLocalString("dlg.browse_btn", "Browse..."));
830         browseJarButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
831             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
832                 browseJarButtonActionPerformed(evt);
833             }
834         });
835
836         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
837         gridBagConstraints.gridx = 2;
838         gridBagConstraints.gridy = 2;
839         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
840         editProjectPanel.add(browseJarButton, gridBagConstraints);
841
842         browseSrcDirButton.setFont(BUTTON_FONT);
843         browseSrcDirButton.setText("Browse");
844         browseSrcDirButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
845         browseSrcDirButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
846         browseSrcDirButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
847         browseSrcDirButton.setText(L10N.getLocalString("dlg.browse_btn", "Browse..."));
848         browseSrcDirButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
849             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
850                 browseSrcDirButtonActionPerformed(evt);
851             }
852         });
853
854         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
855         gridBagConstraints.gridx = 2;
856         gridBagConstraints.gridy = 8;
857         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
858         editProjectPanel.add(browseSrcDirButton, gridBagConstraints);
859
860         editProjectLabel.setBackground(new java.awt.Color JavaDoc(0, 0, 204));
861         editProjectLabel.setFont(LABEL_FONT);
862         editProjectLabel.setForeground(new java.awt.Color JavaDoc(255, 255, 255));
863         editProjectLabel.setText("Project");
864         editProjectLabel.setOpaque(true);
865         editProjectLabel.setText(L10N.getLocalString("dlg.project_lbl", "Project"));
866         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
867         gridBagConstraints.gridx = 0;
868         gridBagConstraints.gridy = 0;
869         gridBagConstraints.gridwidth = 4;
870         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
871         editProjectPanel.add(editProjectLabel, gridBagConstraints);
872
873         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
874         gridBagConstraints.gridx = 0;
875         gridBagConstraints.gridy = 7;
876         gridBagConstraints.gridwidth = 4;
877         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
878         gridBagConstraints.insets = new java.awt.Insets JavaDoc(3, 3, 3, 3);
879         editProjectPanel.add(jSeparator2, gridBagConstraints);
880
881         findBugsButton.setMnemonic('B');
882         findBugsButton.setText("Find Bugs!");
883         findBugsButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
884             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
885                 findBugsButtonActionPerformed(evt);
886             }
887         });
888
889         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
890         gridBagConstraints.gridx = 0;
891         gridBagConstraints.gridy = 21;
892         gridBagConstraints.gridwidth = 4;
893         gridBagConstraints.insets = new java.awt.Insets JavaDoc(3, 3, 3, 3);
894         editProjectPanel.add(findBugsButton, gridBagConstraints);
895
896         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
897         gridBagConstraints.gridx = 0;
898         gridBagConstraints.gridy = 14;
899         gridBagConstraints.gridwidth = 4;
900         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
901         gridBagConstraints.insets = new java.awt.Insets JavaDoc(3, 3, 3, 3);
902         editProjectPanel.add(jSeparator4, gridBagConstraints);
903
904         jarFileListScrollPane.setPreferredSize(new java.awt.Dimension JavaDoc(259, 1));
905         jarFileList.setBorder(new javax.swing.border.BevelBorder JavaDoc(javax.swing.border.BevelBorder.LOWERED));
906         jarFileList.setFont(BUTTON_FONT);
907         disableEditKeyBindings(jarFileList);
908
909         jarFileList.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
910             @Override JavaDoc
911             public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
912                 focusGainedHandler(evt);
913             }
914         });
915
916         jarFileListScrollPane.setViewportView(jarFileList);
917
918         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
919         gridBagConstraints.gridx = 1;
920         gridBagConstraints.gridy = 3;
921         gridBagConstraints.gridwidth = 2;
922         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
923         gridBagConstraints.weighty = 0.4;
924         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
925         editProjectPanel.add(jarFileListScrollPane, gridBagConstraints);
926
927         sourceDirListScrollPane.setPreferredSize(new java.awt.Dimension JavaDoc(259, 1));
928         sourceDirList.setBorder(new javax.swing.border.BevelBorder JavaDoc(javax.swing.border.BevelBorder.LOWERED));
929         sourceDirList.setFont(BUTTON_FONT);
930         disableEditKeyBindings(sourceDirList);
931         sourceDirList.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
932             @Override JavaDoc
933             public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
934                 focusGainedHandler(evt);
935             }
936         });
937
938         sourceDirListScrollPane.setViewportView(sourceDirList);
939
940         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
941         gridBagConstraints.gridx = 1;
942         gridBagConstraints.gridy = 9;
943         gridBagConstraints.gridwidth = 2;
944         gridBagConstraints.gridheight = 3;
945         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
946         gridBagConstraints.weighty = 0.1;
947         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
948         editProjectPanel.add(sourceDirListScrollPane, gridBagConstraints);
949
950         classpathEntryLabel.setFont(BUTTON_FONT);
951         classpathEntryLabel.setText("Classpath entry:");
952         classpathEntryLabel.setText(L10N.getLocalString("dlg.classpathfile_lbl", "Classpath entry:"));
953         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
954         gridBagConstraints.gridx = 0;
955         gridBagConstraints.gridy = 15;
956         gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
957         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 0, 3);
958         editProjectPanel.add(classpathEntryLabel, gridBagConstraints);
959
960         classpathEntryListLabel.setFont(BUTTON_FONT);
961         classpathEntryListLabel.setText("Classpath entries:");
962         classpathEntryListLabel.setText(L10N.getLocalString("dlg.classpathlist_lbl", "Classpath entries:"));
963         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
964         gridBagConstraints.gridx = 0;
965         gridBagConstraints.gridy = 16;
966         gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
967         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 0, 3);
968         editProjectPanel.add(classpathEntryListLabel, gridBagConstraints);
969
970         classpathEntryTextField.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
971             @Override JavaDoc
972             public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
973                 focusGainedHandler(evt);
974             }
975         });
976
977         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
978         gridBagConstraints.gridx = 1;
979         gridBagConstraints.gridy = 15;
980         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
981         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 0);
982         editProjectPanel.add(classpathEntryTextField, gridBagConstraints);
983
984         browseClasspathEntryButton.setFont(BUTTON_FONT);
985         browseClasspathEntryButton.setText("Browse");
986         browseClasspathEntryButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
987         browseClasspathEntryButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
988         browseClasspathEntryButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
989         browseClasspathEntryButton.setText(L10N.getLocalString("dlg.browse_btn", "Browse..."));
990         browseClasspathEntryButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
991             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
992                 browseClasspathEntryButtonActionPerformed(evt);
993             }
994         });
995
996         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
997         gridBagConstraints.gridx = 2;
998         gridBagConstraints.gridy = 15;
999         editProjectPanel.add(browseClasspathEntryButton, gridBagConstraints);
1000
1001        addClasspathEntryButton.setFont(BUTTON_FONT);
1002        addClasspathEntryButton.setText("Add");
1003        addClasspathEntryButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
1004        addClasspathEntryButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
1005        addClasspathEntryButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
1006        addClasspathEntryButton.setText(L10N.getLocalString("dlg.add_btn", "Add"));
1007        addClasspathEntryButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1008            public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1009                addClasspathEntryButtonActionPerformed(evt);
1010            }
1011        });
1012
1013        gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1014        gridBagConstraints.gridx = 3;
1015        gridBagConstraints.gridy = 15;
1016        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
1017        gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 0);
1018        editProjectPanel.add(addClasspathEntryButton, gridBagConstraints);
1019
1020        removeClasspathEntryButton.setFont(BUTTON_FONT);
1021        removeClasspathEntryButton.setText("Remove");
1022        removeClasspathEntryButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
1023        removeClasspathEntryButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
1024        removeClasspathEntryButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
1025        removeClasspathEntryButton.setText(L10N.getLocalString("dlg.remove_btn", "Remove"));
1026        removeClasspathEntryButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1027            public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1028                removeClasspathEntryButtonActionPerformed(evt);
1029            }
1030        });
1031
1032        gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1033        gridBagConstraints.gridx = 3;
1034        gridBagConstraints.gridy = 16;
1035        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
1036        gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 0);
1037        editProjectPanel.add(removeClasspathEntryButton, gridBagConstraints);
1038
1039        classpathEntryListScrollPane.setPreferredSize(new java.awt.Dimension JavaDoc(259, 1));
1040        classpathEntryList.setBorder(new javax.swing.border.BevelBorder JavaDoc(javax.swing.border.BevelBorder.LOWERED));
1041        classpathEntryList.setFont(BUTTON_FONT);
1042        disableEditKeyBindings(classpathEntryList);
1043        classpathEntryList.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
1044            @Override JavaDoc
1045            public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
1046                focusGainedHandler(evt);
1047            }
1048        });
1049
1050        classpathEntryListScrollPane.setViewportView(classpathEntryList);
1051
1052        gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1053        gridBagConstraints.gridx = 1;
1054        gridBagConstraints.gridy = 16;
1055        gridBagConstraints.gridwidth = 2;
1056        gridBagConstraints.gridheight = 3;
1057        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
1058        gridBagConstraints.weighty = 0.1;
1059        gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 3, 0, 3);
1060        editProjectPanel.add(classpathEntryListScrollPane, gridBagConstraints);
1061
1062        gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1063        gridBagConstraints.gridx = 0;
1064        gridBagConstraints.gridy = 20;
1065        gridBagConstraints.gridwidth = 4;
1066        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
1067        gridBagConstraints.insets = new java.awt.Insets JavaDoc(3, 0, 3, 0);
1068        editProjectPanel.add(jSeparator5, gridBagConstraints);
1069
1070        sourceUpButton.setFont(BUTTON_FONT);
1071        sourceUpButton.setText("Up");
1072        sourceUpButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
1073        sourceUpButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
1074        sourceUpButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
1075        sourceUpButton.setText(L10N.getLocalString("dlg.up_btn", "Up"));
1076        sourceUpButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1077            public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1078                sourceUpButtonActionPerformed(evt);
1079            }
1080        });
1081
1082        gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1083        gridBagConstraints.gridx = 3;
1084        gridBagConstraints.gridy = 10;
1085        gridBagConstraints.weighty = 0.2;
1086        editProjectPanel.add(sourceUpButton, gridBagConstraints);
1087
1088        sourceDownButton.setFont(BUTTON_FONT);
1089        sourceDownButton.setText("Down");
1090        sourceDownButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
1091        sourceDownButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
1092        sourceDownButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
1093        sourceDownButton.setText(L10N.getLocalString("dlg.down_btn", "Down"));
1094        sourceDownButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1095            public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1096                sourceDownButtonActionPerformed(evt);
1097            }
1098        });
1099
1100        gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1101        gridBagConstraints.gridy = 11;
1102        editProjectPanel.add(sourceDownButton, gridBagConstraints);
1103
1104        classpathUpButton.setFont(BUTTON_FONT);
1105        classpathUpButton.setText("Up");
1106        classpathUpButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
1107        classpathUpButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
1108        classpathUpButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
1109        classpathUpButton.setText(L10N.getLocalString("dlg.up_btn", "Up"));
1110        classpathUpButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1111            public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1112                classpathUpButtonActionPerformed(evt);
1113            }
1114        });
1115
1116        gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1117        gridBagConstraints.gridx = 3;
1118        gridBagConstraints.gridy = 17;
1119        gridBagConstraints.weighty = 0.2;
1120        editProjectPanel.add(classpathUpButton, gridBagConstraints);
1121
1122        classpathDownButton.setFont(BUTTON_FONT);
1123        classpathDownButton.setText("Down");
1124        classpathDownButton.setMaximumSize(new java.awt.Dimension JavaDoc(90, 25));
1125        classpathDownButton.setMinimumSize(new java.awt.Dimension JavaDoc(90, 25));
1126        classpathDownButton.setPreferredSize(new java.awt.Dimension JavaDoc(90, 25));
1127        classpathDownButton.setText(L10N.getLocalString("dlg.down_btn", "Down"));
1128        classpathDownButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1129            public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1130                classpathDownButtonActionPerformed(evt);
1131            }
1132        });
1133
1134        gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1135        gridBagConstraints.gridx = 3;
1136        gridBagConstraints.gridy = 18;
1137        editProjectPanel.add(classpathDownButton, gridBagConstraints);
1138
1139        viewPanel.add(editProjectPanel, "EditProjectPanel");
1140
1141        bugTreePanel.setLayout(new java.awt.GridBagLayout JavaDoc());
1142
1143        bugTreeBugDetailsSplitter.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
1144        bugTreeBugDetailsSplitter.setResizeWeight(1.0);
1145        bugTreeBugDetailsSplitter.setOneTouchExpandable(true);
1146        bugTreeBugDetailsSplitter.addPropertyChangeListener(new java.beans.PropertyChangeListener JavaDoc() {
1147            public void propertyChange(java.beans.PropertyChangeEvent JavaDoc evt) {
1148                bugTreeBugDetailsSplitterPropertyChange(evt);
1149            }
1150        });
1151
1152        byClassBugTree.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
1153            @Override JavaDoc
1154            public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
1155                focusGainedHandler(evt);
1156            }
1157        });
1158
1159        byClassScrollPane.setViewportView(byClassBugTree);
1160
1161        groupByTabbedPane.addTab("By Class", byClassScrollPane);
1162
1163        byPackageBugTree.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
1164            @Override JavaDoc
1165            public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
1166                focusGainedHandler(evt);
1167            }
1168        });
1169
1170        byPackageScrollPane.setViewportView(byPackageBugTree);
1171
1172        groupByTabbedPane.addTab("By Package", byPackageScrollPane);
1173
1174        byBugTypeBugTree.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
1175            @Override JavaDoc
1176            public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
1177                focusGainedHandler(evt);
1178            }
1179        });
1180
1181        byBugTypeScrollPane.setViewportView(byBugTypeBugTree);
1182
1183        groupByTabbedPane.addTab("By Bug Type", byBugTypeScrollPane);
1184
1185        byBugCategoryBugTree.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
1186            @Override JavaDoc
1187            public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
1188                focusGainedHandler(evt);
1189            }
1190        });
1191
1192        byBugCategoryScrollPane.setViewportView(byBugCategoryBugTree);
1193
1194        groupByTabbedPane.addTab("By Category Type", byBugCategoryScrollPane);
1195
1196        bugSummaryEditorPane.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
1197            @Override JavaDoc
1198            public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
1199                focusGainedHandler(evt);
1200            }
1201        });
1202
1203        bySummary.setViewportView(bugSummaryEditorPane);
1204
1205        groupByTabbedPane.addTab("Summary", bySummary);
1206
1207        bugTreeBugDetailsSplitter.setTopComponent(groupByTabbedPane);
1208
1209        bugDescriptionEditorPane.setEditable(false);
1210        bugDescriptionEditorPane.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
1211            @Override JavaDoc
1212            public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
1213                focusGainedHandler(evt);
1214            }
1215        });
1216
1217        bugDescriptionScrollPane.setViewportView(bugDescriptionEditorPane);
1218
1219        bugDetailsTabbedPane.addTab("Details", bugDescriptionScrollPane);
1220
1221        sourceTextAreaScrollPane.setMinimumSize(new java.awt.Dimension JavaDoc(22, 180));
1222        sourceTextAreaScrollPane.setPreferredSize(new java.awt.Dimension JavaDoc(0, 100));
1223        sourceTextArea.setEditable(false);
1224        sourceTextArea.setFont(SOURCE_FONT);
1225        sourceTextArea.setEnabled(false);
1226        sourceTextArea.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
1227            @Override JavaDoc
1228            public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
1229                focusGainedHandler(evt);
1230            }
1231        });
1232
1233
1234        sourceTextAreaScrollPane.setViewportView(sourceTextArea);
1235        sourceLineNumberer = new LineNumberer(sourceTextArea);
1236        sourceLineNumberer.setBackground(Color.WHITE);
1237        sourceTextAreaScrollPane.setRowHeaderView(sourceLineNumberer);
1238
1239        bugDetailsTabbedPane.addTab("Source code", sourceTextAreaScrollPane);
1240
1241        annotationTextArea.addFocusListener(new java.awt.event.FocusAdapter JavaDoc() {
1242            @Override JavaDoc
1243            public void focusGained(java.awt.event.FocusEvent JavaDoc evt) {
1244                focusGainedHandler(evt);
1245            }
1246        });
1247
1248        annotationTextAreaScrollPane.setViewportView(annotationTextArea);
1249
1250        bugDetailsTabbedPane.addTab("Annotations", annotationTextAreaScrollPane);
1251
1252        bugTreeBugDetailsSplitter.setBottomComponent(bugDetailsTabbedPane);
1253
1254        gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1255        gridBagConstraints.gridx = 0;
1256        gridBagConstraints.gridy = 1;
1257        gridBagConstraints.gridwidth = 2;
1258        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
1259        gridBagConstraints.weightx = 1.0;
1260        gridBagConstraints.weighty = 1.0;
1261        bugTreePanel.add(bugTreeBugDetailsSplitter, gridBagConstraints);
1262
1263        viewPanel.add(bugTreePanel, "BugTree");
1264
1265        {
1266            equalizeControls( new JComponent JavaDoc[]
1267                {
1268                    addJarButton,
1269                    addSourceDirButton,
1270                    addClasspathEntryButton,
1271                    removeJarButton,
1272                    removeSrcDirButton,
1273                    removeClasspathEntryButton,
1274                    browseJarButton,
1275                    browseSrcDirButton,
1276                    browseClasspathEntryButton,
1277                    sourceUpButton,
1278                    sourceDownButton,
1279                    classpathUpButton,
1280                    classpathDownButton
1281                });
1282
1283                groupByTabbedPane.setTitleAt(0, L10N.getLocalString( "dlg.byclass_tab", "By Class"));
1284                groupByTabbedPane.setTitleAt(1, L10N.getLocalString( "dlg.bypackage_tab", "By Package"));
1285                groupByTabbedPane.setTitleAt(2, L10N.getLocalString( "dlg.bybugtype_tab", "By Bug Type"));
1286                groupByTabbedPane.setTitleAt(3, L10N.getLocalString( "dlg.bybugcategory_tab", "By Bug Category"));
1287                groupByTabbedPane.setTitleAt(4, L10N.getLocalString( "dlg.summary_tab", "Summary"));
1288                bugDetailsTabbedPane.setTitleAt(0, L10N.getLocalString( "dlg.details_tab", "Details"));
1289                bugDetailsTabbedPane.setTitleAt(1, L10N.getLocalString( "dlg.sourcecode_tab", "Source Code"));
1290                bugDetailsTabbedPane.setTitleAt(2, L10N.getLocalString( "dlg.annotations_tab", "Annotations"));
1291            }
1292
1293            gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1294            gridBagConstraints.gridx = 0;
1295            gridBagConstraints.gridy = 0;
1296            gridBagConstraints.gridwidth = 2;
1297            gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
1298            gridBagConstraints.weightx = 1.0;
1299            gridBagConstraints.weighty = 1.0;
1300            getContentPane().add(viewPanel, gridBagConstraints);
1301
1302            urlLabel.setFont(BUTTON_FONT);
1303            urlLabel.setText("FindBugs - http://findbugs.sourceforge.net/");
1304            gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1305            gridBagConstraints.gridx = 0;
1306            gridBagConstraints.gridy = 1;
1307            gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
1308            gridBagConstraints.insets = new java.awt.Insets JavaDoc(2, 2, 2, 0);
1309            getContentPane().add(urlLabel, gridBagConstraints);
1310
1311            jPanel1.setLayout(new javax.swing.BoxLayout JavaDoc(jPanel1, javax.swing.BoxLayout.X_AXIS));
1312
1313            jPanel1.add(logoLabel);
1314
1315            growBoxSpacer.setMaximumSize(new java.awt.Dimension JavaDoc(16, 16));
1316            jPanel1.add(growBoxSpacer);
1317
1318            gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
1319            gridBagConstraints.gridx = 1;
1320            gridBagConstraints.gridy = 1;
1321            gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHEAST;
1322            gridBagConstraints.insets = new java.awt.Insets JavaDoc(2, 0, 2, 2);
1323            getContentPane().add(jPanel1, gridBagConstraints);
1324
1325            theMenuBar.setFont(BUTTON_FONT);
1326            fileMenu.setText("File");
1327            fileMenu.setFont(BUTTON_FONT);
1328            localiseButton(fileMenu, "menu.file_menu", "&File", true);
1329            fileMenu.addMenuListener(new javax.swing.event.MenuListener JavaDoc() {
1330                public void menuCanceled(javax.swing.event.MenuEvent JavaDoc evt) {
1331                }
1332                public void menuDeselected(javax.swing.event.MenuEvent JavaDoc evt) {
1333                }
1334                public void menuSelected(javax.swing.event.MenuEvent JavaDoc evt) {
1335                    fileMenuMenuSelected(evt);
1336                }
1337            });
1338
1339            newProjectItem.setFont(BUTTON_FONT);
1340            newProjectItem.setText("New Project");
1341            localiseButton(newProjectItem, "menu.new_item", "&New Project", true);
1342            newProjectItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1343                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1344                    newProjectItemActionPerformed(evt);
1345                }
1346            });
1347
1348            fileMenu.add(newProjectItem);
1349
1350            openProjectItem.setFont(BUTTON_FONT);
1351            openProjectItem.setText("Open Project...");
1352            localiseButton(openProjectItem, "menu.open_item", "&Open Project...", true);
1353            openProjectItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1354                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1355                    openProjectItemActionPerformed(evt);
1356                }
1357            });
1358
1359            fileMenu.add(openProjectItem);
1360
1361            recentProjectsMenu.setText("Recent Projects");
1362            recentProjectsMenu.setFont(BUTTON_FONT);
1363            localiseButton(recentProjectsMenu, "menu.recent_menu", "R&ecent Projects", true);
1364            rebuildRecentProjectsMenu();
1365            fileMenu.add(recentProjectsMenu);
1366
1367            fileMenu.add(jSeparator9);
1368
1369            closeProjectItem.setFont(BUTTON_FONT);
1370            closeProjectItem.setText("Close Project");
1371            localiseButton(closeProjectItem, "menu.close_item", "&Close Project", true);
1372            closeProjectItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1373                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1374                    closeProjectItemActionPerformed(evt);
1375                }
1376            });
1377
1378            fileMenu.add(closeProjectItem);
1379
1380            saveProjectItem.setFont(BUTTON_FONT);
1381            saveProjectItem.setText("Save Project");
1382            localiseButton(saveProjectItem, "menu.save_item", "&Save Project", true);
1383            saveProjectItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1384                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1385                    saveProjectItemActionPerformed(evt);
1386                }
1387            });
1388
1389            fileMenu.add(saveProjectItem);
1390
1391            saveProjectAsItem.setFont(BUTTON_FONT);
1392            saveProjectAsItem.setText("Save Project As...");
1393            localiseButton(saveProjectAsItem, "menu.saveas_item", "Save Project &As...", true);
1394            saveProjectAsItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1395                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1396                    saveProjectAsItemActionPerformed(evt);
1397                }
1398            });
1399
1400            fileMenu.add(saveProjectAsItem);
1401
1402            reloadProjectItem.setFont(BUTTON_FONT);
1403            reloadProjectItem.setText("Reload Project");
1404            localiseButton(reloadProjectItem, "menu.reload_item", "&Reload Project", true);
1405            reloadProjectItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1406                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1407                    reloadProjectItemActionPerformed(evt);
1408                }
1409            });
1410
1411            fileMenu.add(reloadProjectItem);
1412
1413            fileMenu.add(jSeparator3);
1414
1415            loadBugsItem.setFont(BUTTON_FONT);
1416            loadBugsItem.setText("Load Bugs...");
1417            localiseButton(loadBugsItem, "menu.loadbugs_item", "&Load Bugs...", true);
1418            loadBugsItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1419                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1420                    loadBugsItemActionPerformed(evt);
1421                }
1422            });
1423
1424            fileMenu.add(loadBugsItem);
1425
1426            saveBugsItem.setFont(BUTTON_FONT);
1427            saveBugsItem.setText("Save Bugs");
1428            localiseButton(saveBugsItem, "menu.savebugs_item", "Save &Bugs...", true);
1429            saveBugsItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1430                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1431                    saveBugsItemActionPerformed(evt);
1432                }
1433            });
1434
1435            fileMenu.add(saveBugsItem);
1436
1437            fileMenu.add(jSeparator6);
1438
1439            exitItem.setFont(BUTTON_FONT);
1440            exitItem.setText("Exit");
1441            localiseButton(exitItem, "menu.exit_item", "E&xit", true);
1442            exitItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1443                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1444                    exitItemActionPerformed(evt);
1445                }
1446            });
1447
1448            fileMenu.add(exitItem);
1449
1450            theMenuBar.add(fileMenu);
1451
1452            editMenu.setText("Edit");
1453            editMenu.setFont(BUTTON_FONT);
1454            editMenu.setEnabled(false);
1455            localiseButton(editMenu, "menu.edit_menu", "&Edit", true);
1456            cutItem.setFont(BUTTON_FONT);
1457            cutItem.setText("Cut");
1458            localiseButton(cutItem, "menu.cut_item", "Cut", true);
1459            cutItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1460                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1461                    cutActionPerformed(evt);
1462                }
1463            });
1464
1465            editMenu.add(cutItem);
1466
1467            copyItem.setFont(BUTTON_FONT);
1468            copyItem.setText("Copy");
1469            localiseButton(copyItem, "menu.copy_item", "Copy", true);
1470            copyItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1471                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1472                    copyActionPerformed(evt);
1473                }
1474            });
1475
1476            editMenu.add(copyItem);
1477
1478            pasteItem.setFont(BUTTON_FONT);
1479            pasteItem.setText("Paste");
1480            localiseButton(pasteItem, "menu.paste_item", "Paste", true);
1481            pasteItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1482                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1483                    pasteActionPerformed(evt);
1484                }
1485            });
1486
1487            editMenu.add(pasteItem);
1488
1489            editMenu.add(jSeparator10);
1490
1491            selectAllItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.CTRL_MASK));
1492            selectAllItem.setFont(BUTTON_FONT);
1493            selectAllItem.setText("Select All");
1494            localiseButton(selectAllItem, "menu.selectall_item", "Select &All", true);
1495            selectAllItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1496                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1497                    selectAllActionPerformed(evt);
1498                }
1499            });
1500
1501            editMenu.add(selectAllItem);
1502
1503            theMenuBar.add(editMenu);
1504
1505            viewMenu.setText("View");
1506            viewMenu.setFont(BUTTON_FONT);
1507            localiseButton(viewMenu, "menu.view_menu", "&View", true);
1508
1509            viewMenu.addMenuListener(new javax.swing.event.MenuListener JavaDoc() {
1510                public void menuCanceled(javax.swing.event.MenuEvent JavaDoc evt) {
1511                }
1512                public void menuDeselected(javax.swing.event.MenuEvent JavaDoc evt) {
1513                }
1514                public void menuSelected(javax.swing.event.MenuEvent JavaDoc evt) {
1515                    viewMenuMenuSelected(evt);
1516                }
1517            });
1518
1519            viewBugDetailsItem.setFont(BUTTON_FONT);
1520            viewBugDetailsItem.setSelected(true);
1521            viewBugDetailsItem.setText("Bug Details");
1522            localiseButton(viewBugDetailsItem, "menu.bugdetails_item", "Bug &Details", true);
1523            viewBugDetailsItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1524                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1525                    viewBugDetailsItemActionPerformed(evt);
1526                }
1527            });
1528
1529            viewMenu.add(viewBugDetailsItem);
1530
1531            fullDescriptionsItem.setFont(BUTTON_FONT);
1532            fullDescriptionsItem.setSelected(true);
1533            fullDescriptionsItem.setText("Full Descriptions");
1534            localiseButton(fullDescriptionsItem, "menu.fulldescriptions_item", "&Full Descriptions", true);
1535            fullDescriptionsItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1536                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1537                    fullDescriptionsItemActionPerformed(evt);
1538                }
1539            });
1540
1541            viewMenu.add(fullDescriptionsItem);
1542
1543            viewMenu.add(jSeparator7);
1544
1545            filterWarningsMenu.setText("Filter Warnings");
1546            filterWarningsMenu.setFont(BUTTON_FONT);
1547            localiseButton(filterWarningsMenu, "menu.filterwarnings_menu", "Filter &Warnings", true);
1548            expPriorityButton.setFont(BUTTON_FONT);
1549            expPriorityButton.setText("Experimental Priority");
1550            priorityButtonGroup.add(expPriorityButton);
1551            localiseButton(expPriorityButton, "menu.exppriority_item", "&Experimental Priority", true);
1552            expPriorityButton.setSelected(getPriorityThreshold() == Detector.EXP_PRIORITY);
1553            expPriorityButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1554                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1555                    expPriorityButtonActionPerformed(evt);
1556                }
1557            });
1558
1559            filterWarningsMenu.add(expPriorityButton);
1560
1561            lowPriorityButton.setFont(BUTTON_FONT);
1562            lowPriorityButton.setText("Low Priority");
1563            priorityButtonGroup.add(lowPriorityButton);
1564            localiseButton(lowPriorityButton, "menu.lowpriority_item", "&Low Priority", true);
1565            lowPriorityButton.setSelected(getPriorityThreshold() == Detector.LOW_PRIORITY);
1566            lowPriorityButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1567                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1568                    lowPriorityButtonActionPerformed(evt);
1569                }
1570            });
1571
1572            filterWarningsMenu.add(lowPriorityButton);
1573
1574            mediumPriorityButton.setFont(BUTTON_FONT);
1575            mediumPriorityButton.setText("Medium Priority");
1576            priorityButtonGroup.add(mediumPriorityButton);
1577            localiseButton(mediumPriorityButton, "menu.mediumpriority_item", "&Medium Priority", true);
1578            mediumPriorityButton.setSelected(getPriorityThreshold() == Detector.NORMAL_PRIORITY);
1579            mediumPriorityButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1580                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1581                    mediumPriorityButtonActionPerformed(evt);
1582                }
1583            });
1584
1585            filterWarningsMenu.add(mediumPriorityButton);
1586
1587            highPriorityButton.setFont(BUTTON_FONT);
1588            highPriorityButton.setText("High Priority");
1589            priorityButtonGroup.add(highPriorityButton);
1590            localiseButton(highPriorityButton, "menu.highpriority_item", "&High Priority", true);
1591            highPriorityButton.setSelected(getPriorityThreshold() == Detector.HIGH_PRIORITY);
1592            highPriorityButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1593                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1594                    highPriorityButtonActionPerformed(evt);
1595                }
1596            });
1597
1598            filterWarningsMenu.add(highPriorityButton);
1599
1600            filterWarningsMenu.add(jSeparator11);
1601
1602            viewMenu.add(filterWarningsMenu);
1603
1604            ButtonGroup JavaDoc bg = new ButtonGroup JavaDoc();
1605            bg.add(expPriorityButton);
1606            bg.add(lowPriorityButton);
1607            bg.add(mediumPriorityButton);
1608            bg.add(highPriorityButton);
1609
1610            viewMenu.add(jSeparator8);
1611
1612            viewProjectItem.setFont(BUTTON_FONT);
1613            viewProjectItem.setText("View Project Details");
1614            viewProjectItem.setEnabled(false);
1615            localiseButton(viewProjectItem, "menu.viewprojectdetails_item", "View Project Details", true);
1616            viewProjectItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1617                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1618                    viewProjectItemActionPerformed(evt);
1619                }
1620            });
1621
1622            viewMenu.add(viewProjectItem);
1623
1624            viewBugsItem.setFont(BUTTON_FONT);
1625            viewBugsItem.setText("View Bugs");
1626            viewBugsItem.setEnabled(false);
1627            localiseButton(viewBugsItem, "menu.viewbugs_item", "View Bugs", true);
1628            viewBugsItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1629                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1630                    viewBugsItemActionPerformed(evt);
1631                }
1632            });
1633
1634            viewMenu.add(viewBugsItem);
1635
1636            theMenuBar.add(viewMenu);
1637
1638            settingsMenu.setText("Settings");
1639            settingsMenu.setFont(BUTTON_FONT);
1640            localiseButton(settingsMenu, "menu.settings_menu", "&Settings", true);
1641            settingsMenu.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1642                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1643                    settingsMenuActionPerformed(evt);
1644                }
1645            });
1646
1647            configureDetectorsItem.setFont(BUTTON_FONT);
1648            configureDetectorsItem.setText("Configure Detectors...");
1649            localiseButton(configureDetectorsItem, "menu.configure_item", "&Configure Detectors...", true);
1650            configureDetectorsItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1651                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1652                    configureDetectorsItemActionPerformed(evt);
1653                }
1654            });
1655
1656            settingsMenu.add(configureDetectorsItem);
1657
1658            effortMenu.setText("Effort");
1659            effortMenu.setFont(BUTTON_FONT);
1660            localiseButton(effortMenu, "menu.effort_menu", "Effort", true);
1661            minEffortItem.setFont(BUTTON_FONT);
1662            minEffortItem.setText("Minimum");
1663            effortButtonGroup.add(minEffortItem);
1664            localiseButton(minEffortItem, "menu.mineffort_item", "&Minimum", true);
1665            minEffortItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1666                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1667                    minEffortItemActionPerformed(evt);
1668                }
1669            });
1670
1671            effortMenu.add(minEffortItem);
1672
1673            normalEffortItem.setFont(BUTTON_FONT);
1674            normalEffortItem.setSelected(true);
1675            normalEffortItem.setText("Normal");
1676            effortButtonGroup.add(normalEffortItem);
1677            localiseButton(normalEffortItem, "menu.normaleffort_item", "&Normal", true);
1678            normalEffortItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1679                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1680                    normalEffortItemActionPerformed(evt);
1681                }
1682            });
1683
1684            effortMenu.add(normalEffortItem);
1685
1686            maxEffortItem.setFont(BUTTON_FONT);
1687            maxEffortItem.setText("Maximum");
1688            effortButtonGroup.add(maxEffortItem);
1689            localiseButton(maxEffortItem, "menu.maxeffort_item", "&Maximum", true);
1690            maxEffortItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1691                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1692                    maxEffortItemActionPerformed(evt);
1693                }
1694            });
1695
1696            effortMenu.add(maxEffortItem);
1697
1698            settingsMenu.add(effortMenu);
1699
1700            theMenuBar.add(settingsMenu);
1701
1702            helpMenu.setText("Help");
1703            helpMenu.setFont(BUTTON_FONT);
1704            localiseButton(helpMenu, "menu.help_menu", "&Help", true);
1705            aboutItem.setFont(BUTTON_FONT);
1706            aboutItem.setText("About...");
1707            localiseButton(aboutItem, "menu.about_item", "&About", true);
1708            aboutItem.addActionListener(new java.awt.event.ActionListener JavaDoc() {
1709                public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
1710                    aboutItemActionPerformed(evt);
1711                }
1712            });
1713
1714            helpMenu.add(aboutItem);
1715
1716            theMenuBar.add(helpMenu);
1717
1718            setJMenuBar(theMenuBar);
1719
1720            pack();
1721        }//GEN-END:initComponents
1722

1723    private void maxEffortItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_maxEffortItemActionPerformed
1724
settingList = FindBugs.MAX_EFFORT;
1725    }//GEN-LAST:event_maxEffortItemActionPerformed
1726

1727    private void normalEffortItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_normalEffortItemActionPerformed
1728
settingList = FindBugs.DEFAULT_EFFORT;
1729    }//GEN-LAST:event_normalEffortItemActionPerformed
1730

1731    private void minEffortItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_minEffortItemActionPerformed
1732
settingList = FindBugs.MIN_EFFORT;
1733    }//GEN-LAST:event_minEffortItemActionPerformed
1734

1735    private void settingsMenuActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_settingsMenuActionPerformed
1736
// TODO add your handling code here:
1737
}//GEN-LAST:event_settingsMenuActionPerformed
1738

1739    private void formWindowOpened(java.awt.event.WindowEvent JavaDoc evt) {//GEN-FIRST:event_formWindowOpened
1740
if (SystemProperties.getBoolean("findbugs.noSummary")) {
1741            groupByTabbedPane.remove(bySummary);
1742        }
1743    }//GEN-LAST:event_formWindowOpened
1744

1745    private void selectAllActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_selectAllActionPerformed
1746
if (selectedComponent == null)
1747            return;
1748        
1749        if (selectedComponent instanceof JTextComponent JavaDoc)
1750            ((JTextComponent JavaDoc)selectedComponent).selectAll();
1751        else if (selectedComponent instanceof JList JavaDoc) {
1752            JList JavaDoc list = (JList JavaDoc)selectedComponent;
1753            list.setSelectionInterval(0, list.getModel().getSize()-1);
1754        }
1755    }//GEN-LAST:event_selectAllActionPerformed
1756

1757    private void disableEditKeyBindings(JList JavaDoc list) {
1758        list.getInputMap().put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.CTRL_MASK), "none");
1759        list.getInputMap().put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_MASK), "none");
1760        list.getInputMap().put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.event.InputEvent.CTRL_MASK), "none");
1761    }
1762    
1763    private String JavaDoc buildSelectPath(JList JavaDoc list) {
1764        StringBuffer JavaDoc path = new StringBuffer JavaDoc();
1765        int[] indices = list.getSelectedIndices();
1766        String JavaDoc separatorStr = SystemProperties.getProperty("path.separator");
1767        String JavaDoc sep = "";
1768        ListModel JavaDoc m = list.getModel();
1769        for (int indice : indices) {
1770            path.append(sep);
1771            sep = separatorStr;
1772            path.append(m.getElementAt(indice));
1773        }
1774        return path.toString();
1775    }
1776    
1777    private void pasteActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_pasteActionPerformed
1778
if (selectedComponent == null)
1779            return;
1780        
1781        if (selectedComponent instanceof JTextComponent JavaDoc)
1782            ((JTextComponent JavaDoc)selectedComponent).paste();
1783        else if (selectedComponent instanceof JList JavaDoc) {
1784            Clipboard JavaDoc cb = Toolkit.getDefaultToolkit().getSystemClipboard();
1785            Transferable JavaDoc transfer = cb.getContents(this);
1786            if (transfer.isDataFlavorSupported(DataFlavor.stringFlavor)) {
1787                try {
1788                    String JavaDoc path = (String JavaDoc)transfer.getTransferData(DataFlavor.stringFlavor);
1789
1790                    if (selectedComponent == jarFileList) {
1791                        jarNameTextField.setText(path);
1792                        addJarButtonActionPerformed(evt);
1793                    }
1794                    else if (selectedComponent == sourceDirList) {
1795                        srcDirTextField.setText(path);
1796                        this.addSourceDirButtonActionPerformed(evt);
1797                    }
1798                    else if (selectedComponent == classpathEntryList) {
1799                        classpathEntryTextField.setText(path);
1800                        addClasspathEntryButtonActionPerformed(evt);
1801                    }
1802                } catch (Exception JavaDoc e) {
1803                }
1804            }
1805        }
1806    }//GEN-LAST:event_pasteActionPerformed
1807

1808    private void copyActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_copyActionPerformed
1809
if (selectedComponent == null)
1810            return;
1811        
1812        if (selectedComponent instanceof JTextComponent JavaDoc)
1813            ((JTextComponent JavaDoc)selectedComponent).copy();
1814        else if (selectedComponent instanceof JTree JavaDoc) {
1815            TreePath JavaDoc path = ((JTree JavaDoc)selectedComponent).getSelectionPath();
1816            StringSelection JavaDoc data = new StringSelection JavaDoc(path.getLastPathComponent().toString());
1817            Clipboard JavaDoc cb = Toolkit.getDefaultToolkit().getSystemClipboard();
1818            cb.setContents(data, data);
1819       }
1820        else if (selectedComponent instanceof JList JavaDoc) {
1821            StringSelection JavaDoc path = new StringSelection JavaDoc(buildSelectPath((JList JavaDoc)selectedComponent));
1822            Clipboard JavaDoc cb = Toolkit.getDefaultToolkit().getSystemClipboard();
1823            cb.setContents(path, path);
1824        }
1825    }//GEN-LAST:event_copyActionPerformed
1826

1827    private void cutActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_cutActionPerformed
1828
if (selectedComponent == null)
1829            return;
1830        
1831        if (selectedComponent instanceof JTextComponent JavaDoc)
1832            ((JTextComponent JavaDoc)selectedComponent).cut();
1833        else if (selectedComponent instanceof JList JavaDoc) {
1834            StringSelection JavaDoc path = new StringSelection JavaDoc(buildSelectPath((JList JavaDoc)selectedComponent));
1835            Clipboard JavaDoc cb = Toolkit.getDefaultToolkit().getSystemClipboard();
1836            cb.setContents(path, path);
1837            if (selectedComponent == jarFileList)
1838                removeJarButtonActionPerformed(evt);
1839            else if (selectedComponent == sourceDirList)
1840                removeSrcDirButtonActionPerformed(evt);
1841            else if (selectedComponent == classpathEntryList)
1842                removeClasspathEntryButtonActionPerformed(evt);
1843        }
1844    }//GEN-LAST:event_cutActionPerformed
1845

1846    private void focusGainedHandler(java.awt.event.FocusEvent JavaDoc evt) {//GEN-FIRST:event_focusGainedHandler
1847
Component JavaDoc old = evt.getOppositeComponent();
1848        if (old instanceof JList JavaDoc)
1849            ((JList JavaDoc) old).clearSelection();
1850        selectedComponent = evt.getComponent();
1851        ableEditMenu();
1852    }//GEN-LAST:event_focusGainedHandler
1853

1854    private void classpathUpButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_classpathUpButtonActionPerformed
1855
if (moveEntriesUp(classpathEntryList))
1856            resyncAuxClasspathEntries();
1857    }//GEN-LAST:event_classpathUpButtonActionPerformed
1858

1859    private void sourceDownButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_sourceDownButtonActionPerformed
1860
if (moveEntriesDown(sourceDirList))
1861            resyncSourceEntries();
1862    }//GEN-LAST:event_sourceDownButtonActionPerformed
1863

1864    private void sourceUpButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_sourceUpButtonActionPerformed
1865
if (moveEntriesUp(sourceDirList))
1866            resyncSourceEntries();
1867    }//GEN-LAST:event_sourceUpButtonActionPerformed
1868

1869    private void classpathDownButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_classpathDownButtonActionPerformed
1870
if (moveEntriesDown(classpathEntryList))
1871            resyncAuxClasspathEntries();
1872    }//GEN-LAST:event_classpathDownButtonActionPerformed
1873

1874    private void viewBugsItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_viewBugsItemActionPerformed
1875
setView("BugTree");
1876    }//GEN-LAST:event_viewBugsItemActionPerformed
1877

1878    private void viewProjectItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_viewProjectItemActionPerformed
1879
setView("EditProjectPanel");
1880    }//GEN-LAST:event_viewProjectItemActionPerformed
1881

1882    private void highPriorityButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_highPriorityButtonActionPerformed
1883
setPriorityThreshold(Detector.HIGH_PRIORITY);
1884    }//GEN-LAST:event_highPriorityButtonActionPerformed
1885

1886    private void mediumPriorityButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_mediumPriorityButtonActionPerformed
1887
setPriorityThreshold(Detector.NORMAL_PRIORITY);
1888    }//GEN-LAST:event_mediumPriorityButtonActionPerformed
1889

1890    private void lowPriorityButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_lowPriorityButtonActionPerformed
1891
setPriorityThreshold(Detector.LOW_PRIORITY);
1892    }//GEN-LAST:event_lowPriorityButtonActionPerformed
1893

1894    private void expPriorityButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_expPriorityButtonActionPerformed
1895
setPriorityThreshold(Detector.EXP_PRIORITY);
1896    }//GEN-LAST:event_expPriorityButtonActionPerformed
1897

1898    private void saveBugsItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_saveBugsItemActionPerformed
1899

1900        try {
1901            if (currentAnalysisRun == null) {
1902                logger.logMessage(Logger.ERROR, "No bugs are loaded!");
1903                return;
1904            }
1905
1906            JFileChooser JavaDoc chooser = createFileChooser();
1907            chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1908            chooser.setFileFilter(xmlFileFilter);
1909
1910            int result = chooseFile(chooser, L10N.getLocalString("dlg.savebugs_ttl", "Save Bugs"));
1911
1912            if (result != JFileChooser.CANCEL_OPTION) {
1913                // Make sure current annotation text is up to date with its
1914
// corresponding bug instance
1915
if (currentBugInstance != null)
1916                    synchBugAnnotation(currentBugInstance);
1917
1918                // Save bugs to file
1919
File JavaDoc selectedFile = chooser.getSelectedFile();
1920                currentAnalysisRun.saveBugsToFile(selectedFile);
1921            }
1922        } catch (Exception JavaDoc e) {
1923            if (FindBugs.DEBUG) {
1924                e.printStackTrace();
1925            }
1926            logger.logMessage(Logger.ERROR, "Could not save bugs: " + e.toString());
1927        }
1928    }//GEN-LAST:event_saveBugsItemActionPerformed
1929

1930    private void loadBugsFromFile(File JavaDoc file) throws IOException JavaDoc, DocumentException {
1931        File JavaDoc selectedFile = file;
1932
1933        Project project = new Project();
1934        AnalysisRun analysisRun = new AnalysisRun(project, this);
1935
1936        analysisRun.loadBugsFromFile(selectedFile);
1937
1938        project.setProjectFileName(file.getName()); // otherwise frame will show "<<unnamed project>>"
1939
setProject(project);
1940        synchAnalysisRun(analysisRun);
1941    }
1942    
1943    private void loadBugsFromURL(String JavaDoc urlspec) throws IOException JavaDoc, DocumentException {
1944        URL JavaDoc url = new URL JavaDoc(urlspec);
1945        InputStream JavaDoc in = url.openStream();
1946        
1947        Project project = new Project();
1948        AnalysisRun analysisRun = new AnalysisRun(project, this);
1949        
1950        analysisRun.loadBugsFromInputStream(in);
1951        
1952        setProject(project);
1953        synchAnalysisRun(analysisRun);
1954    }
1955    
1956    private void loadBugsItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_loadBugsItemActionPerformed
1957
// FIXME: offer to save current project and bugs
1958

1959        try {
1960
1961            JFileChooser JavaDoc chooser = createFileChooser();
1962            chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1963            chooser.setFileFilter(xmlFileFilter);
1964
1965            int result = chooseFile(chooser, L10N.getLocalString("dlg.loadbugs_ttl", "Load Bugs..."));
1966
1967            if (result != JFileChooser.CANCEL_OPTION) {
1968                loadBugsFromFile(chooser.getSelectedFile());
1969            }
1970        } catch (Exception JavaDoc e) {
1971            if (FindBugs.DEBUG) {
1972                e.printStackTrace();
1973            }
1974            logger.logMessage(Logger.ERROR, "Could not load bugs: " + e.toString());
1975        }
1976
1977    }//GEN-LAST:event_loadBugsItemActionPerformed
1978

1979    private void configureDetectorsItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_configureDetectorsItemActionPerformed
1980
ConfigureDetectorsDialog dialog = new ConfigureDetectorsDialog(this, true);
1981        dialog.setSize(700, 520);
1982        dialog.setLocationRelativeTo(null); // center the dialog
1983
dialog.setVisible(true);
1984    }//GEN-LAST:event_configureDetectorsItemActionPerformed
1985

1986    private void reloadProjectItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_reloadProjectItemActionPerformed
1987
Project current = getCurrentProject();
1988
1989        if (current == null)
1990            return;
1991
1992        try {
1993            String JavaDoc filename = current.getProjectFileName();
1994            Project project = new Project();
1995            project.read(filename);
1996            setProject(null);
1997            setProject(project);
1998            findBugsButtonActionPerformed(evt);
1999        } catch (IOException JavaDoc e) {
2000            logger.logMessage(Logger.ERROR, "Could not reload project: " + e.getMessage());
2001        }
2002
2003    }//GEN-LAST:event_reloadProjectItemActionPerformed
2004

2005    private void saveProjectAsItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_saveProjectAsItemActionPerformed
2006
saveProject(getCurrentProject(), L10N.getLocalString("dlg.saveprojectas_ttl", "Save Project As..."), true);
2007    }//GEN-LAST:event_saveProjectAsItemActionPerformed
2008

2009    private void viewMenuMenuSelected(javax.swing.event.MenuEvent JavaDoc evt) {//GEN-FIRST:event_viewMenuMenuSelected
2010
// View bug details and full descriptions items,
2011
// are only enabled if there is a project open.
2012
boolean hasProject = getCurrentProject() != null;
2013        viewBugDetailsItem.setEnabled(hasProject);
2014        fullDescriptionsItem.setEnabled(hasProject);
2015    }//GEN-LAST:event_viewMenuMenuSelected
2016

2017    private void fileMenuMenuSelected(javax.swing.event.MenuEvent JavaDoc evt) {//GEN-FIRST:event_fileMenuMenuSelected
2018
// Save and close project items are only enabled if there is a project open.
2019
boolean hasProject = getCurrentProject() != null;
2020        saveProjectItem.setEnabled(hasProject);
2021        saveProjectAsItem.setEnabled(hasProject);
2022        reloadProjectItem.setEnabled(hasProject && !getCurrentProject().getProjectFileName().equals(Project.UNNAMED_PROJECT));
2023        closeProjectItem.setEnabled(hasProject);
2024
2025        // Save bugs is only enabled if there is a current analysis run
2026
boolean hasAnalysisRun = currentAnalysisRun != null;
2027        saveBugsItem.setEnabled(hasAnalysisRun);
2028
2029    }//GEN-LAST:event_fileMenuMenuSelected
2030

2031    private void closeProjectItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_closeProjectItemActionPerformed
2032
if (closeProjectHook(getCurrentProject(), L10N.getLocalString("dlg.closeproject_lbl", "Close Project"))) {
2033            setProject(null);
2034        }
2035    }//GEN-LAST:event_closeProjectItemActionPerformed
2036

2037    private void removeClasspathEntryButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_removeClasspathEntryButtonActionPerformed
2038
Project project = getCurrentProject();
2039        DefaultListModel JavaDoc listModel = (DefaultListModel JavaDoc) classpathEntryList.getModel();
2040
2041        int[] selIndices = classpathEntryList.getSelectedIndices();
2042        for (int i = selIndices.length - 1; i >= 0; i--) {
2043            int sel = selIndices[i];
2044            project.removeAuxClasspathEntry(sel);
2045            listModel.remove(sel);
2046        }
2047    }//GEN-LAST:event_removeClasspathEntryButtonActionPerformed
2048

2049    private void addClasspathEntryButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_addClasspathEntryButtonActionPerformed
2050
addClasspathEntryToList();
2051    }//GEN-LAST:event_addClasspathEntryButtonActionPerformed
2052

2053    private void browseClasspathEntryButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_browseClasspathEntryButtonActionPerformed
2054
JFileChooser JavaDoc chooser = createFileChooser();
2055        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
2056        chooser.setFileFilter(auxClasspathEntryFileFilter);
2057        chooser.setMultiSelectionEnabled(true);
2058
2059        int result = chooseFile(chooser, "Add Entry");
2060
2061        if (result != JFileChooser.CANCEL_OPTION) {
2062            File JavaDoc[] selectedFileList = chooser.getSelectedFiles();
2063            for (int i = 0; i < selectedFileList.length; ++i) {
2064                selectedFileList[i] = verifyFileSelection(selectedFileList[i]);
2065                String JavaDoc entry = selectedFileList[i].getPath();
2066                addClasspathEntryToProject(entry);
2067            }
2068        }
2069    }//GEN-LAST:event_browseClasspathEntryButtonActionPerformed
2070

2071    private void fullDescriptionsItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_fullDescriptionsItemActionPerformed
2072
for (JTree JavaDoc bugTree : bugTreeList) {
2073            // Redisplay the displayed bug instance nodes
2074
DefaultTreeModel JavaDoc bugTreeModel = (DefaultTreeModel JavaDoc) bugTree.getModel();
2075            int numRows = bugTree.getRowCount();
2076
2077            for (int i = 0; i < numRows; ++i) {
2078                //System.out.println("Getting path for row " + i);
2079
TreePath JavaDoc path = bugTree.getPathForRow(i);
2080                if (path == null)
2081                    continue;
2082                DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) path.getLastPathComponent();
2083                if (node instanceof BugTreeNode)
2084                    bugTreeModel.valueForPathChanged(path, node.getUserObject());
2085            }
2086        }
2087    }//GEN-LAST:event_fullDescriptionsItemActionPerformed
2088

2089    private void viewBugDetailsItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_viewBugDetailsItemActionPerformed
2090
String JavaDoc view = getView();
2091        if (view.equals("BugTree")) {
2092            checkBugDetailsVisibility();
2093        }
2094
2095    }//GEN-LAST:event_viewBugDetailsItemActionPerformed
2096

2097    private void bugTreeBugDetailsSplitterPropertyChange(java.beans.PropertyChangeEvent JavaDoc evt) {//GEN-FIRST:event_bugTreeBugDetailsSplitterPropertyChange
2098
// Here we want to
2099
// (1) Keep the View:Bug details checkbox item up to date, and
2100
// (2) keep the details window synchronized with the current bug instance
2101
String JavaDoc propertyName = evt.getPropertyName();
2102        if (propertyName.equals(JSplitPane.DIVIDER_LOCATION_PROPERTY)) {
2103            boolean isMaximized = isSplitterMaximized(bugTreeBugDetailsSplitter, evt);
2104            viewBugDetailsItem.setSelected(!isMaximized);
2105            if (!isMaximized) {
2106                // Details window is shown, so make sure it is populated
2107
// with bug detail information
2108
synchBugInstance();
2109            }
2110        }
2111    }//GEN-LAST:event_bugTreeBugDetailsSplitterPropertyChange
2112

2113    private void openProjectItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_openProjectItemActionPerformed
2114

2115        if (!closeProjectHook(getCurrentProject(), L10N.getLocalString("msg.openproject_txt", "Open Project")))
2116            return;
2117
2118        JFileChooser JavaDoc chooser = createFileChooser();
2119        chooser.setFileFilter(projectFileFilter);
2120        int result = chooseFileToOpen(chooser);
2121
2122        if (result == JFileChooser.CANCEL_OPTION)
2123            return;
2124        try {
2125            File JavaDoc file = chooser.getSelectedFile();
2126            Project project = new Project();
2127            project.read(file.getPath());
2128            setProject(project);
2129            UserPreferences.getUserPreferences().useProject(file.getPath());
2130            rebuildRecentProjectsMenu();
2131
2132        } catch (IOException JavaDoc e) {
2133            logger.logMessage(Logger.ERROR, MessageFormat.format( L10N.getLocalString("msg.couldnotopenproject_txt", "Could not open project: {0}"), new Object JavaDoc[]{e.getMessage()}));
2134        }
2135    }//GEN-LAST:event_openProjectItemActionPerformed
2136

2137    private void saveProjectItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_saveProjectItemActionPerformed
2138
saveProject(getCurrentProject(), L10N.getLocalString("msg.saveproject_txt", "Save Project"));
2139    }//GEN-LAST:event_saveProjectItemActionPerformed
2140

2141    private void aboutItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_aboutItemActionPerformed
2142
about();
2143    }//GEN-LAST:event_aboutItemActionPerformed
2144

2145    private void findBugsButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_findBugsButtonActionPerformed
2146
Project project = getCurrentProject();
2147
2148        if (project.getFileCount() == 0) {
2149            logger.logMessage(Logger.ERROR, MessageFormat.format(L10N.getLocalString("msg.projectnojars_txt", "Project {0} has no Jar files selected"), new Object JavaDoc[]{project}));
2150            return;
2151        }
2152
2153        bugDescriptionEditorPane.setText("");
2154        currentBugDetailsKey = null;
2155        sourceTextArea.setText("");
2156        AnalysisRun analysisRun = new AnalysisRun(project, this);
2157
2158        logger.logMessage(Logger.INFO, MessageFormat.format(L10N.getLocalString("msg.beginninganalysis_txt", "Beginning analysis of {0}"), new Object JavaDoc[]{project}));
2159
2160        // Run the analysis!
2161
RunAnalysisDialog dialog = new RunAnalysisDialog(this, analysisRun);
2162        dialog.setSize(400, 300);
2163        dialog.setLocationRelativeTo(null); // center the dialog
2164
dialog.setVisible(true);
2165
2166        if (dialog.isCompleted()) {
2167            logger.logMessage(Logger.INFO, MessageFormat.format(L10N.getLocalString("msg.analysiscompleted_txt", "Analysis {0} completed"), new Object JavaDoc[]{project}));
2168
2169            // Report any errors that might have occurred during analysis
2170
analysisRun.reportAnalysisErrors();
2171
2172            // Now we have an analysis run to look at
2173
synchAnalysisRun(analysisRun);
2174        } else {
2175            if (dialog.exceptionOccurred()) {
2176                // The analysis was killed by an unexpected exception
2177
Exception JavaDoc e = dialog.getException();
2178                AnalysisErrorDialog err = new AnalysisErrorDialog(this, true, null);
2179                err.addLine(MessageFormat.format(L10N.getLocalString("msg.fatalanalysisexception_txt", "Fatal analysis exception: {0}"), new Object JavaDoc[]{e.toString()}));
2180                StackTraceElement JavaDoc[] callList = e.getStackTrace();
2181                for (StackTraceElement JavaDoc aCallList : callList)
2182                    err.addLine("\t" + aCallList);
2183                err.finish();
2184                err.setSize(650, 500);
2185                err.setLocationRelativeTo(null); // center the dialog
2186
err.setVisible(true);
2187            } else {
2188                // Cancelled by user
2189
logger.logMessage(Logger.INFO, MessageFormat.format(L10N.getLocalString("msg.analysiscancelled_txt", "Analysis of {0} cancelled by user"), new Object JavaDoc[]{project}));
2190            }
2191        }
2192    }//GEN-LAST:event_findBugsButtonActionPerformed
2193

2194    private void browseSrcDirButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_browseSrcDirButtonActionPerformed
2195
JFileChooser JavaDoc chooser = createFileChooser();
2196        chooser.setFileFilter(archiveAndDirectoryFilter);
2197        chooser.setMultiSelectionEnabled(true);
2198        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
2199
2200        int rc = chooseFile(chooser, L10N.getLocalString("msg_addsource_lbl", "Add source directory or archive"));
2201        if (rc == JFileChooser.APPROVE_OPTION) {
2202            File JavaDoc[] selectedFileList = chooser.getSelectedFiles();
2203            for (int i = 0; i < selectedFileList.length; ++i) {
2204                selectedFileList[i] = verifyFileSelection(selectedFileList[i]);
2205                String JavaDoc entry = selectedFileList[i].getPath();
2206                addSrcToProject(entry);
2207            }
2208        }
2209    }//GEN-LAST:event_browseSrcDirButtonActionPerformed
2210

2211    private void srcDirTextFieldActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_srcDirTextFieldActionPerformed
2212
addSourceDirToList();
2213    }//GEN-LAST:event_srcDirTextFieldActionPerformed
2214

2215    private void jarNameTextFieldActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_jarNameTextFieldActionPerformed
2216
addJarToList();
2217    }//GEN-LAST:event_jarNameTextFieldActionPerformed
2218

2219    private void browseJarButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_browseJarButtonActionPerformed
2220
JFileChooser JavaDoc chooser = createFileChooser();
2221        chooser.setFileFilter(archiveAndDirectoryFilter);
2222        chooser.setMultiSelectionEnabled(true);
2223        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
2224
2225        int rc = chooseFile(chooser, L10N.getLocalString("msg.addarchiveordirectory_txt", "Add archive or directory"));
2226        if (rc == JFileChooser.APPROVE_OPTION) {
2227            File JavaDoc[] selectedFileList = chooser.getSelectedFiles();
2228            for (int i = 0; i < selectedFileList.length; ++i) {
2229                selectedFileList[i] = verifyFileSelection(selectedFileList[i]);
2230                String JavaDoc entry = selectedFileList[i].getPath();
2231                addJarToProject(entry);
2232            }
2233        }
2234    }//GEN-LAST:event_browseJarButtonActionPerformed
2235

2236    private void newProjectItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_newProjectItemActionPerformed
2237

2238        if (!closeProjectHook(getCurrentProject(), L10N.getLocalString("msg.newproject_txt", "New Project")))
2239            return;
2240
2241        Project project = new Project();
2242        setProject(project);
2243    }//GEN-LAST:event_newProjectItemActionPerformed
2244

2245    private void exitItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_exitItemActionPerformed
2246
exitFindBugs();
2247    }//GEN-LAST:event_exitItemActionPerformed
2248

2249    private void removeSrcDirButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_removeSrcDirButtonActionPerformed
2250
Project project = getCurrentProject();
2251        DefaultListModel JavaDoc listModel = (DefaultListModel JavaDoc) sourceDirList.getModel();
2252
2253        int[] selIndices = sourceDirList.getSelectedIndices();
2254        for (int i = selIndices.length - 1; i >= 0; i--) {
2255            int sel = selIndices[i];
2256            project.removeSourceDir(sel);
2257            listModel.remove(sel);
2258        }
2259    }//GEN-LAST:event_removeSrcDirButtonActionPerformed
2260

2261    private void removeJarButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_removeJarButtonActionPerformed
2262
Project project = getCurrentProject();
2263        DefaultListModel JavaDoc listModel = (DefaultListModel JavaDoc) jarFileList.getModel();
2264
2265        int[] selIndices = jarFileList.getSelectedIndices();
2266        for (int i = selIndices.length - 1; i >= 0; i--) {
2267            int sel = selIndices[i];
2268            project.removeFile(sel);
2269            listModel.remove(sel);
2270        }
2271    }//GEN-LAST:event_removeJarButtonActionPerformed
2272

2273    private void addSourceDirButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_addSourceDirButtonActionPerformed
2274
addSourceDirToList();
2275    }//GEN-LAST:event_addSourceDirButtonActionPerformed
2276

2277    private void addJarButtonActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_addJarButtonActionPerformed
2278
addJarToList();
2279    }//GEN-LAST:event_addJarButtonActionPerformed
2280

2281    /**
2282     * Exit the Application
2283     */

2284    private void exitForm(java.awt.event.WindowEvent JavaDoc evt) {//GEN-FIRST:event_exitForm
2285
exitFindBugs();
2286    }//GEN-LAST:event_exitForm
2287

2288    /**
2289     * This makes the set of controls passed in all the same size, equal to
2290     * the minimum needed of the largest control.
2291     */

2292    private void equalizeControls(JComponent JavaDoc[] components) {
2293        Dimension JavaDoc d;
2294
2295        int minX = 0, minY = 0;
2296        for (JComponent JavaDoc comp : components) {
2297            comp.setMaximumSize(null);
2298            comp.setMinimumSize(null);
2299            comp.setPreferredSize(null);
2300            d = comp.getPreferredSize();
2301            if (d.width > minX)
2302                minX = d.width;
2303            if (d.height > minY)
2304                minY = d.height;
2305        }
2306
2307        d = new Dimension JavaDoc(minX, minY);
2308        for (JComponent JavaDoc comp : components) {
2309            comp.setMinimumSize(d);
2310            comp.setMaximumSize(d);
2311            comp.setPreferredSize(d);
2312        }
2313    }
2314
2315    /**
2316     * This is called whenever the selection is changed in the bug tree.
2317     *
2318     * @param e the TreeSelectionEvent
2319     */

2320    private void bugTreeSelectionChanged(TreeSelectionEvent JavaDoc e) {
2321
2322        BugInstance selected = getCurrentBugInstance();
2323        if (selected != null) {
2324            synchBugInstance();
2325        }
2326    }
2327
2328    private void openRecentProjectItemActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
2329        if (!closeProjectHook(getCurrentProject(), L10N.getLocalString("msg.openproject_txt", "Open Project")))
2330            return;
2331
2332        JMenuItem JavaDoc recentProjectItem = (JMenuItem JavaDoc) evt.getSource();
2333        File JavaDoc file = new File JavaDoc(recentProjectItem.getText());
2334        try {
2335            System.setProperty("user.dir", file.getParent());
2336            Project project = new Project();
2337            project.read(file.getPath());
2338            setProject(project);
2339            UserPreferences.getUserPreferences().useProject(file.getPath());
2340        } catch (IOException JavaDoc e) {
2341            UserPreferences.getUserPreferences().removeProject(file.getPath());
2342            logger.logMessage(Logger.ERROR, MessageFormat.format(L10N.getLocalString("msg.couldnotopenproject_txt", "Could not open project: {0}"), new Object JavaDoc[]{e.getMessage()}));
2343        } finally {
2344            rebuildRecentProjectsMenu();
2345        }
2346    }
2347
2348    private boolean moveEntriesUp(JList JavaDoc entryList) {
2349        int[] selIndices = entryList.getSelectedIndices();
2350        if (selIndices.length == 0)
2351            return false;
2352
2353        boolean changed = false;
2354        int lastInsertPos = -1;
2355        DefaultListModel JavaDoc model = (DefaultListModel JavaDoc) entryList.getModel();
2356        for (int i = 0; i < selIndices.length; i++) {
2357            int sel = selIndices[i];
2358            if ((sel - 1) > lastInsertPos) {
2359                model.add(sel - 1, model.remove(sel));
2360                selIndices[i] = sel - 1;
2361                changed = true;
2362            }
2363            lastInsertPos = selIndices[i];
2364        }
2365
2366        entryList.setSelectedIndices(selIndices);
2367        return changed;
2368    }
2369
2370    private boolean moveEntriesDown(JList JavaDoc entryList) {
2371        int[] selIndices = entryList.getSelectedIndices();
2372        if (selIndices.length == 0)
2373            return false;
2374
2375        boolean changed = false;
2376        DefaultListModel JavaDoc model = (DefaultListModel JavaDoc) entryList.getModel();
2377        int lastInsertPos = model.getSize();
2378        for (int i = selIndices.length - 1; i >= 0; i--) {
2379            int sel = selIndices[i];
2380            if ((sel + 1) < lastInsertPos) {
2381                model.add(sel + 1, model.remove(sel));
2382                selIndices[i] = sel + 1;
2383                changed = true;
2384            }
2385            lastInsertPos = selIndices[i];
2386        }
2387
2388        entryList.setSelectedIndices(selIndices);
2389        return changed;
2390    }
2391
2392    private void resyncAuxClasspathEntries() {
2393        Project project = getCurrentProject();
2394        int numEntries = project.getNumAuxClasspathEntries();
2395        while (numEntries-- > 0)
2396            project.removeAuxClasspathEntry(0);
2397
2398        DefaultListModel JavaDoc model = (DefaultListModel JavaDoc) classpathEntryList.getModel();
2399        for (int i = 0; i < model.size(); i++)
2400            project.addAuxClasspathEntry((String JavaDoc) model.get(i));
2401    }
2402
2403    private void resyncSourceEntries() {
2404        Project project = getCurrentProject();
2405        int numEntries = project.getNumSourceDirs();
2406        while (numEntries-- > 0)
2407            project.removeSourceDir(0);
2408
2409        DefaultListModel JavaDoc model = (DefaultListModel JavaDoc) sourceDirList.getModel();
2410        for (int i = 0; i < model.size(); i++)
2411            project.addSourceDir((String JavaDoc) model.get(i));
2412    }
2413
2414    /**
2415     * Localise the given AbstractButton, setting the text and optionally mnemonic
2416     * Note that AbstractButton includes menus and menu items.
2417     * @param button The button to localise
2418     * @param key The key to look up in resource bundle
2419     * @param defaultString default String to use if key not found
2420     * @param setMnemonic whether or not to set the mnemonic. According to Sun's
2421     * guidelines, default/cancel buttons should not have mnemonics
2422     * but instead should use Return/Escape
2423     */

2424    private void localiseButton(AbstractButton JavaDoc button, String JavaDoc key, String JavaDoc defaultString,
2425                                boolean setMnemonic) {
2426        L10N.localiseButton(button, key, defaultString, setMnemonic);
2427    }
2428
2429    /* ----------------------------------------------------------------------
2430     * Component initialization support
2431     * ---------------------------------------------------------------------- */

2432
2433    /**
2434     * This is called from the constructor to perform post-initialization
2435     * of the components in the form.
2436     */

2437    private void postInitComponents() {
2438        logger = new ConsoleLogger(this);
2439
2440        // Add menu items for bug categories to View->Filter Settings menu.
2441
// These are automatically localized assuming that a
2442
// BugCategoryDescriptions_<locale>.properties file exists
2443
// in edu.umd.cs.findbugs.
2444
Collection JavaDoc<String JavaDoc> bugCategoryCollection = edu.umd.cs.findbugs.I18N.instance().getBugCategories();
2445        this.bugCategoryCheckBoxList = new JCheckBoxMenuItem JavaDoc[bugCategoryCollection.size()];
2446        this.bugCategoryList = new String JavaDoc[bugCategoryCollection.size()];
2447        int count = 0;
2448        for (String JavaDoc bugCategory : bugCategoryCollection) {
2449            String JavaDoc bugCategoryDescription = I18N.instance().getBugCategoryDescription(bugCategory);
2450
2451            final JCheckBoxMenuItem JavaDoc item = new JCheckBoxMenuItem JavaDoc(bugCategoryDescription, true);
2452            item.setFont(BUTTON_FONT);
2453            item.setSelected(getFilterSettings().containsCategory(bugCategory));
2454            item.addActionListener(new ActionListener JavaDoc() {
2455                public void actionPerformed(ActionEvent JavaDoc evt) {
2456                    toggleBugCategory(item);
2457                }
2458            });
2459
2460            filterWarningsMenu.add(item);
2461
2462            this.bugCategoryCheckBoxList[count] = item;
2463            this.bugCategoryList[count] = bugCategory;
2464
2465            ++count;
2466        }
2467        
2468        viewPanelLayout = (CardLayout JavaDoc) viewPanel.getLayout();
2469        
2470        // List of bug group tabs.
2471
// This must be in the same order as GROUP_BY_ORDER_LIST!
2472
bugTreeList = new JTree JavaDoc[]{byClassBugTree, byPackageBugTree, byBugTypeBugTree, byBugCategoryBugTree};
2473        
2474        // Configure bug trees
2475
for (JTree JavaDoc bugTree : bugTreeList) {
2476            bugTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
2477            bugTree.setCellRenderer(BugCellRenderer.instance());
2478            bugTree.setRootVisible(false);
2479            bugTree.setShowsRootHandles(true);
2480            bugTree.addTreeSelectionListener(new TreeSelectionListener JavaDoc() {
2481                public void valueChanged(TreeSelectionEvent JavaDoc e) {
2482                    bugTreeSelectionChanged(e);
2483                }
2484            });
2485        }
2486        
2487        jarFileList.setModel(new DefaultListModel JavaDoc());
2488        sourceDirList.setModel(new DefaultListModel JavaDoc());
2489        classpathEntryList.setModel(new DefaultListModel JavaDoc());
2490        
2491        // We use a special highlight painter to ensure that the highlights cover
2492
// complete source lines, even though the source text doesn't
2493
// fill the lines completely.
2494
final Highlighter.HighlightPainter JavaDoc painter =
2495                new DefaultHighlighter.DefaultHighlightPainter JavaDoc(sourceTextArea.getSelectionColor()) {
2496            @Override JavaDoc
2497            public Shape JavaDoc paintLayer(Graphics JavaDoc g, int offs0, int offs1,
2498                    Shape JavaDoc bounds, JTextComponent JavaDoc c, View JavaDoc view) {
2499                try {
2500                    Shape JavaDoc extent = view.modelToView(offs0, Position.Bias.Forward, offs1, Position.Bias.Backward, bounds);
2501                    Rectangle JavaDoc rect = extent.getBounds();
2502                    rect.x = 0;
2503                    rect.width = bounds.getBounds().width;
2504                    g.setColor(getColor());
2505                    g.fillRect(rect.x, rect.y, rect.width, rect.height);
2506                    return rect;
2507                } catch (BadLocationException JavaDoc e) {
2508                    return null;
2509                }
2510            }
2511        };
2512        Highlighter JavaDoc sourceHighlighter = new DefaultHighlighter JavaDoc() {
2513            @Override JavaDoc
2514            public Object JavaDoc addHighlight(int p0, int p1, Highlighter.HighlightPainter JavaDoc p)
2515            throws BadLocationException JavaDoc {
2516                return super.addHighlight(p0, p1, painter);
2517            }
2518        };
2519        sourceTextArea.setHighlighter(sourceHighlighter);
2520        
2521        updateTitle(getCurrentProject());
2522        
2523        // Load the icon for the UMD logo
2524
ClassLoader JavaDoc classLoader = this.getClass().getClassLoader();
2525        ImageIcon JavaDoc logoIcon = new ImageIcon JavaDoc(classLoader.getResource("edu/umd/cs/findbugs/gui/logo_umd.png"));
2526        logoLabel.setIcon(logoIcon);
2527        
2528        // Set common Menu Accelerators
2529
final int MENU_MASK = getMenuMask();
2530        newProjectItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, MENU_MASK));
2531        openProjectItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, MENU_MASK));
2532        saveProjectItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, MENU_MASK));
2533        closeProjectItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, MENU_MASK));
2534        reloadProjectItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, MENU_MASK));
2535        
2536        cutItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, MENU_MASK));
2537        copyItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, MENU_MASK));
2538        pasteItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, MENU_MASK));
2539        selectAllItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, MENU_MASK));
2540        
2541        if (MAC_OS_X) {
2542            // Some more accelerators that use modifiers. Other platforms
2543
// tend not to use modifiers for menu accelerators
2544
saveProjectAsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, MENU_MASK | Event.SHIFT_MASK));
2545            loadBugsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, MENU_MASK | Event.ALT_MASK));
2546            saveBugsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, MENU_MASK | Event.ALT_MASK));
2547            
2548            // Leave room for the growBox on Mac
2549
growBoxSpacer.setMinimumSize(new java.awt.Dimension JavaDoc(16,16));
2550            
2551            // Remove Unnecessary/Redundant menu items.
2552
fileMenu.remove(exitItem);
2553            fileMenu.remove(jSeparator6);
2554            theMenuBar.remove(helpMenu);
2555            
2556            // Set up listeners for Quit and About menu items using
2557
// Apple's EAWT API.
2558
// We use reflection here, so there is no posible chance that the
2559
// class loader will try to load OSXAdapter on a non Mac system
2560
try {
2561                Class JavaDoc osxAdapter = Class.forName("edu.umd.cs.findbugs.gui.OSXAdapter");
2562                Class JavaDoc[] defArgs = {FindBugsFrame.class};
2563                Method JavaDoc registerMethod = osxAdapter.getDeclaredMethod("registerMacOSXApplication", defArgs);
2564                if (registerMethod != null) {
2565                    Object JavaDoc[] args = {this};
2566                    registerMethod.invoke(osxAdapter, args);
2567                }
2568            } catch (NoClassDefFoundError JavaDoc e) {
2569                // This will be thrown first if the OSXAdapter is loaded on a system without the EAWT
2570
// because OSXAdapter extends ApplicationAdapter in its def
2571
System.err.println("This version of Mac OS X does not support the Apple EAWT. Application Menu handling has been disabled (" + e + ")");
2572            } catch (ClassNotFoundException JavaDoc e) {
2573                // This shouldn't be reached; if there's a problem with the OSXAdapter we should get the
2574
// above NoClassDefFoundError first.
2575
System.err.println("This version of Mac OS X does not support the Apple EAWT. Application Menu handling has been disabled (" + e + ")");
2576            } catch (Exception JavaDoc e) {
2577                System.err.println("Exception while loading the OSXAdapter: " + e);
2578                if (FindBugs.DEBUG) {
2579                    e.printStackTrace();
2580                }
2581            }
2582        }
2583        
2584    }
2585    
2586    private void rebuildRecentProjectsMenu() {
2587        UserPreferences prefs = UserPreferences.getUserPreferences();
2588        final List JavaDoc<String JavaDoc> recentProjects = prefs.getRecentProjects();
2589        SwingUtilities.invokeLater(new Runnable JavaDoc() {
2590            public void run() {
2591                recentProjectsMenu.removeAll();
2592                java.awt.Font JavaDoc ft = BUTTON_FONT;
2593                if (recentProjects.size() == 0) {
2594                    JMenuItem JavaDoc emptyItem = new JMenuItem JavaDoc(L10N.getLocalString("menu.empty_item", "Empty"));
2595                    emptyItem.setFont(ft);
2596                    emptyItem.setEnabled(false);
2597                    recentProjectsMenu.add(emptyItem);
2598                } else {
2599                    for (String JavaDoc recentProject : recentProjects) {
2600                        JMenuItem JavaDoc projectItem = new JMenuItem JavaDoc(recentProject);
2601                        projectItem.setFont(ft);
2602                        projectItem.addActionListener(new ActionListener JavaDoc() {
2603                            public void actionPerformed(ActionEvent JavaDoc evt) {
2604                                openRecentProjectItemActionPerformed(evt);
2605                            }
2606                        });
2607                        recentProjectsMenu.add(projectItem);
2608                    }
2609                }
2610            }
2611        });
2612    }
2613    
2614    /* ----------------------------------------------------------------------
2615     * Helpers for accessing and modifying UI components
2616     * ---------------------------------------------------------------------- */

2617    
2618    /**
2619     * Based on the current tree selection path, get a user object
2620     * whose class is the same as the given class.
2621     *
2622     * @param tree the tree
2623     * @param c the class
2624     * @return an instance of the given kind of object which is in the
2625     * current selection, or null if there is no matching object
2626     */

2627    private static Object JavaDoc getTreeSelectionOf(JTree JavaDoc tree, Class JavaDoc c) {
2628        TreePath JavaDoc selPath = tree.getSelectionPath();
2629        
2630        // There may not be anything selected at the moment
2631
if (selPath == null)
2632            return null;
2633        
2634        // Work backwards from end until we get to the kind of
2635
// object we're looking for.
2636
Object JavaDoc[] nodeList = selPath.getPath();
2637        for (int i = nodeList.length - 1; i >= 0; --i) {
2638            DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) nodeList[i];
2639            Object JavaDoc nodeInfo = node.getUserObject();
2640            if (nodeInfo != null && nodeInfo.getClass() == c)
2641                return nodeInfo;
2642        }
2643        return null;
2644    }
2645    
2646    /**
2647     * Get the current project.
2648     */

2649    private Project getCurrentProject() {
2650        return currentProject;
2651    }
2652    
2653    /**
2654     * Get the current analysis run.
2655     */

2656    private AnalysisRun getCurrentAnalysisRun() {
2657        return currentAnalysisRun;
2658    }
2659    
2660    /**
2661     * Get the bug instance currently selected in the bug tree.
2662     */

2663    private BugInstance getCurrentBugInstance() {
2664        JTree JavaDoc bugTree = getCurrentBugTree();
2665        if (bugTree != null) {
2666            return (BugInstance) getTreeSelectionOf(bugTree, BugInstance.class);
2667        }
2668        return null;
2669    }
2670    
2671    /**
2672     * Return whether or not the given splitter is "maximized", meaning that
2673     * the top window of the split has been given all of the space.
2674     * Note that this window assumes that the split is vertical (meaning
2675     * that we have top and bottom components).
2676     *
2677     * @param splitter the JSplitPane
2678     * @param evt the event that is changing the splitter value
2679     */

2680    private boolean isSplitterMaximized(JSplitPane JavaDoc splitter, java.beans.PropertyChangeEvent JavaDoc evt) {
2681        Integer JavaDoc location = (Integer JavaDoc) evt.getNewValue();
2682        
2683        int height = splitter.getHeight();
2684        int hopefullyMaxDivider = height - (splitter.getDividerSize() + DIVIDER_FUDGE);
2685        //System.out.println("Splitter: "+(splitter==consoleSplitter?"consoleSplitter":"bugTreeBugDetailsSplitter")+
2686
// ": height="+height+",location="+location+
2687
// ",hopefullyMax="+hopefullyMaxDivider);
2688
boolean isMaximized = location.intValue() >= hopefullyMaxDivider;
2689        return isMaximized;
2690    }
2691    
2692    private void checkBugDetailsVisibility() {
2693        if (viewBugDetailsItem.isSelected()) {
2694            bugTreeBugDetailsSplitter.resetToPreferredSizes();
2695        } else {
2696            bugTreeBugDetailsSplitter.setDividerLocation(1.0);
2697        }
2698        //System.out.("New bug detail splitter location " + bugTreeBugDetailsSplitter.getDividerLocation());
2699
}
2700    
2701    private JTree JavaDoc getCurrentBugTree() {
2702        JScrollPane JavaDoc selected = (JScrollPane JavaDoc) groupByTabbedPane.getSelectedComponent();
2703        Object JavaDoc view = selected.getViewport().getView();
2704        if (view instanceof JTree JavaDoc) {
2705            return (JTree JavaDoc) view;
2706        }
2707        return null;
2708    }
2709    
2710    /* ----------------------------------------------------------------------
2711     * Synchronization of data model and UI
2712     * ---------------------------------------------------------------------- */

2713    
2714    /**
2715     * Set the priority threshold for display of bugs in the bug tree.
2716     *
2717     * @param threshold the threshold
2718     */

2719    private void setPriorityThreshold(int threshold) {
2720        if (threshold != getFilterSettings().getMinPriorityAsInt()) {
2721            getFilterSettings().setMinPriority(ProjectFilterSettings.getIntPriorityAsString(threshold));
2722            if (currentAnalysisRun != null)
2723                synchAnalysisRun(currentAnalysisRun);
2724        }
2725    }
2726    
2727    private void ableEditMenu() {
2728        String JavaDoc view = getView();
2729        if ((view != null) && view.equals("EditProjectPanel")) {
2730            if (selectedComponent != null) {
2731                boolean hasSelection = false;
2732                if (selectedComponent instanceof JList JavaDoc) {
2733                    JList JavaDoc list = (JList JavaDoc)selectedComponent;
2734                    hasSelection = list.getSelectedIndices().length > 0;
2735                } else if (selectedComponent instanceof JTextField JavaDoc) {
2736                    JTextField JavaDoc tf = (JTextField JavaDoc)selectedComponent;
2737                    hasSelection = ((tf.getSelectedText() != null) &&
2738                            (tf.getSelectedText().length() > 0));
2739                }
2740                
2741                cutItem.setEnabled(hasSelection);
2742                copyItem.setEnabled(hasSelection);
2743                selectAllItem.setEnabled(true);
2744            }
2745            // } else if (view.equals("BugTree")) {
2746
// } else if (view.equals("ReportPanel")) {
2747

2748        } else {
2749            cutItem.setEnabled(false);
2750            copyItem.setEnabled(true);
2751            pasteItem.setEnabled(false);
2752            selectAllItem.setEnabled(false);
2753        }
2754    }
2755    
2756    private void setProject(Project project) {
2757        currentProject = project;
2758        if (project != null) {
2759            synchProject(project);
2760            setView("EditProjectPanel");
2761            editMenu.setEnabled(true);
2762            viewProjectItem.setEnabled(true);
2763            viewProjectItem.setSelected(true);
2764            viewBugsItem.setEnabled(false);
2765            viewBugsItem.setSelected(false);
2766        } else {
2767            editMenu.setEnabled(false);
2768            viewProjectItem.setEnabled(false);
2769            viewProjectItem.setSelected(false);
2770            viewBugsItem.setEnabled(false);
2771            viewBugsItem.setSelected(false);
2772            setView("EmptyPanel");
2773        }
2774        updateTitle(project);
2775        ableEditMenu();
2776    }
2777    
2778    private void updateTitle(Project project) {
2779        if (project == null)
2780            this.setTitle(L10N.getLocalString("dlg.noproject_lbl", "FindBugs - no project"));
2781        else
2782            this.setTitle("FindBugs - " + project.toString());
2783    }
2784    
2785    /**
2786     * Save given project.
2787     * If the project already has a valid filename, use that filename.
2788     * Otherwise, prompt for one.
2789     *
2790     * @param project the Project to save
2791     * @param dialogTitle the title for the save dialog (if needed)
2792     */

2793    private boolean saveProject(Project project, String JavaDoc dialogTitle) {
2794        return saveProject(project, dialogTitle, false);
2795    }
2796    
2797    /**
2798     * Offer to save the current Project to a file.
2799     *
2800     * @param project the Project to save
2801     * @param dialogTitle the title for the save dialog (if needed)
2802     * @param chooseFilename if true, force a dialog to prompt the user
2803     * for a filename
2804     * @return true if the project is saved successfully, false if the user
2805     * cancels or an error occurs
2806     */

2807    private boolean saveProject(Project project, String JavaDoc dialogTitle, boolean chooseFilename) {
2808        boolean useRelativePaths;
2809        try {
2810            if (project == null)
2811                return true;
2812            
2813            File JavaDoc file;
2814            String JavaDoc fileName = project.getProjectFileName();
2815            
2816            if (!fileName.startsWith("<") && !chooseFilename) {
2817                file = new File JavaDoc(fileName);
2818                useRelativePaths = project.getOption( Project.RELATIVE_PATHS );
2819            } else {
2820                JRadioButton JavaDoc relativePaths = new JRadioButton JavaDoc(L10N.getLocalString("msg.userelativepaths_txt", "Use Relative Paths"));
2821                relativePaths.setSelected(project.getOption(Project.RELATIVE_PATHS));
2822                JFileChooser JavaDoc chooser = createFileChooser(relativePaths);
2823                chooser.setFileFilter(projectFileFilter);
2824                int result = chooseFile(chooser, dialogTitle);
2825                if (result == JFileChooser.CANCEL_OPTION)
2826                    return false;
2827                file = chooser.getSelectedFile();
2828                fileName = Project.transformFilename(file.getPath());
2829                file = new File JavaDoc(fileName);
2830                useRelativePaths = relativePaths.isSelected();
2831            }
2832            
2833            project.write(file.getPath(), useRelativePaths, file.getParent());
2834            logger.logMessage(Logger.INFO, "Project saved");
2835            project.setProjectFileName(file.getPath());
2836            
2837            UserPreferences prefs = UserPreferences.getUserPreferences();
2838            prefs.useProject(file.getPath());
2839            prefs.read();
2840            rebuildRecentProjectsMenu();
2841            
2842            updateTitle(project);
2843            
2844            return true;
2845        } catch (IOException JavaDoc e) {
2846            logger.logMessage(Logger.ERROR, "Could not save project: " + e.toString());
2847            JOptionPane.showMessageDialog(this, "Error saving project: " + e.toString(),
2848                    "Error", JOptionPane.ERROR_MESSAGE);
2849            return false;
2850        }
2851    }
2852    
2853    /**
2854     * Hook to call before closing a project.
2855     *
2856     * @param project the project being closed
2857     * @param savePromptTitle title to use for the "Save project?" dialog
2858     * @return true if user has confirmed that the project should be closed,
2859     * false if the close is cancelled
2860     */

2861    private boolean closeProjectHook(Project project, String JavaDoc savePromptTitle) {
2862        if (project == null || !project.isModified())
2863            return true;
2864        
2865        // Confirm that the project should be closed.
2866
int option = JOptionPane.showConfirmDialog(this, L10N.getLocalString("msg.saveprojectquery_txt", "Save Project?"), savePromptTitle,
2867                JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
2868        
2869        if (option == JOptionPane.CANCEL_OPTION)
2870            return false;
2871        else if (option == JOptionPane.YES_OPTION) {
2872            boolean result = saveProject(project, "Save Project");
2873            if (result)
2874                JOptionPane.showMessageDialog(this, "Project was successfully saved.");
2875            return result;
2876        } else
2877            return true;
2878    }
2879    
2880    /**
2881     * Synchronize the edit project dialog with given project.
2882     *
2883     * @param project the selected project
2884     */

2885    private void synchProject(Project project) {
2886        // Clear text fields
2887
jarNameTextField.setText("");
2888        srcDirTextField.setText("");
2889        classpathEntryTextField.setText("");
2890        
2891        // Populate jar file, source directory, and aux classpath entry lists
2892

2893        DefaultListModel JavaDoc jarListModel = (DefaultListModel JavaDoc) jarFileList.getModel();
2894        jarListModel.clear();
2895        for (int i = 0; i < project.getFileCount(); ++i) {
2896            jarListModel.addElement(project.getFile(i));
2897        }
2898        
2899        DefaultListModel JavaDoc srcDirListModel = (DefaultListModel JavaDoc) sourceDirList.getModel();
2900        srcDirListModel.clear();
2901        for (int i = 0; i < project.getNumSourceDirs(); ++i) {
2902            srcDirListModel.addElement(project.getSourceDir(i));
2903        }
2904        
2905        DefaultListModel JavaDoc classpathEntryListModel = (DefaultListModel JavaDoc) classpathEntryList.getModel();
2906        classpathEntryListModel.clear();
2907        for (int i = 0; i < project.getNumAuxClasspathEntries(); ++i) {
2908            classpathEntryListModel.addElement(project.getAuxClasspathEntry(i));
2909        }
2910    }
2911    
2912    /**
2913     * Synchronize the bug trees with the given analysisRun object.
2914     *
2915     * @param analysisRun the selected analysis run
2916     */

2917    private void synchAnalysisRun(AnalysisRun analysisRun) {
2918        // Create and populate tree models
2919
for (int i = 0; i < GROUP_BY_ORDER_LIST.length; ++i) {
2920            DefaultMutableTreeNode JavaDoc bugRootNode = new DefaultMutableTreeNode JavaDoc();
2921            DefaultTreeModel JavaDoc bugTreeModel = new DefaultTreeModel JavaDoc(bugRootNode);
2922            
2923            String JavaDoc groupByOrder = GROUP_BY_ORDER_LIST[i];
2924            analysisRun.setTreeModel(groupByOrder, bugTreeModel);
2925            populateAnalysisRunTreeModel(analysisRun, groupByOrder);
2926            if (i < bugTreeList.length)
2927                bugTreeList[i].setModel(bugTreeModel);
2928        }
2929        
2930        currentAnalysisRun = analysisRun;
2931        
2932        //set the summary output
2933
setSummary(analysisRun.getSummary());
2934        setView("BugTree");
2935    }
2936    
2937    private void setSummary(String JavaDoc summaryXML) {
2938        bugSummaryEditorPane.setContentType("text/html");
2939        /*
2940        bugSummaryEditorPane.setText(summaryXML);
2941        // : unfortunately, using setText() on the editor pane
2942        // results in the contents being scrolled to the bottom of the pane.
2943        // An immediate inline call to set the scroll position does nothing.
2944        // So, use invokeLater(), even though this results in flashing.
2945        // [What we really need is a way to set the text WITHOUT changing
2946        // the caret position. Need to investigate.]
2947        SwingUtilities.invokeLater(new Runnable() {
2948            public void run() {
2949                bySummary.getViewport().setViewPosition(new Point(0, 0));
2950            }
2951        });
2952        */

2953        StringReader JavaDoc reader = null;
2954        try {
2955            if (summaryXML != null) {
2956                reader = new StringReader JavaDoc(summaryXML); // no need for BufferedReader
2957
bugSummaryEditorPane.read(reader, "html summary");
2958            } else {
2959                bugSummaryEditorPane.setText("");
2960            }
2961        } catch (IOException JavaDoc e) {
2962            bugSummaryEditorPane.setText("Could not set summary: " + e.getMessage());
2963            logger.logMessage(Logger.WARNING, e.getMessage());
2964        } finally {
2965            if (reader != null)
2966                reader.close(); // polite, but doesn't do much in StringReader
2967
}
2968        
2969    }
2970    
2971    /**
2972     * Populate an analysis run's tree model for given sort order.
2973     */

2974    private void populateAnalysisRunTreeModel(AnalysisRun analysisRun, final String JavaDoc groupBy) {
2975        //System.out.println("Populating bug tree for order " + groupBy);
2976

2977        // Set busy cursor - this is potentially a time-consuming operation
2978
Cursor JavaDoc orig = this.getCursor();
2979        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
2980        
2981        final DefaultTreeModel JavaDoc bugTreeModel = analysisRun.getTreeModel(groupBy);
2982        final DefaultMutableTreeNode JavaDoc bugRootNode = (DefaultMutableTreeNode JavaDoc) bugTreeModel.getRoot();
2983        
2984        // Delete all children from root node
2985
bugRootNode.removeAllChildren();
2986        
2987        // Sort the instances (considering only those that meet the
2988
// priority threshold)
2989
TreeSet JavaDoc<BugInstance> sortedCollection = new TreeSet JavaDoc<BugInstance>(getBugInstanceComparator(groupBy));
2990        for (BugInstance bugInstance : analysisRun.getBugInstances()) {
2991            if (getFilterSettings().displayWarning(bugInstance))
2992                sortedCollection.add(bugInstance);
2993        }
2994        
2995        // The grouper callback is what actually adds the group and bug
2996
// nodes to the tree.
2997
Grouper.Callback<BugInstance> callback = new Grouper.Callback<BugInstance>() {
2998            private BugInstanceGroup currentGroup;
2999            private DefaultMutableTreeNode JavaDoc currentGroupNode;
3000            
3001            public void startGroup(BugInstance member) {
3002                String JavaDoc groupName;
3003                if (groupBy == GROUP_BY_CLASS)
3004                    groupName = member.getPrimaryClass().getClassName();
3005                else if (groupBy == GROUP_BY_PACKAGE) {
3006                    groupName = member.getPrimaryClass().getPackageName();
3007                    if (groupName.equals(""))
3008                        groupName = "Unnamed package";
3009                } else if (groupBy == GROUP_BY_BUG_TYPE) {
3010                    String JavaDoc desc = member.toString();
3011                    String JavaDoc shortBugType = desc.substring(0, desc.indexOf(':'));
3012                    String JavaDoc bugTypeDescription = I18N.instance().getBugTypeDescription(shortBugType);
3013                    groupName = shortBugType + ": " + bugTypeDescription;
3014                } else if (groupBy == GROUP_BY_BUG_CATEGORY) {
3015                    BugPattern pattern = member.getBugPattern();
3016                    if (pattern == null) {
3017                        if (FindBugs.DEBUG)
3018                            System.out.println("Unknown bug pattern " + member.getType());
3019                        groupName = "Unknown category";
3020                    } else {
3021                        groupName = I18N.instance().getBugCategoryDescription(pattern.getCategory());
3022                    }
3023                } else
3024                    throw new IllegalStateException JavaDoc("Unknown sort order: " + groupBy);
3025                currentGroup = new BugInstanceGroup(groupBy, groupName);
3026                currentGroupNode = new DefaultMutableTreeNode JavaDoc(currentGroup);
3027                bugTreeModel.insertNodeInto(currentGroupNode, bugRootNode, bugRootNode.getChildCount());
3028                
3029                insertIntoGroup(member);
3030            }
3031            
3032            public void addToGroup(BugInstance member) {
3033                insertIntoGroup(member);
3034            }
3035            
3036            private void insertIntoGroup(BugInstance member) {
3037                int count = currentGroup.getMemberCount();
3038                currentGroup.incrementMemberCount();
3039                BugTreeNode bugNode = new BugTreeNode(member);
3040                if (BUG_COUNT)
3041                    bugNode.setCount(count);
3042                bugTreeModel.insertNodeInto(bugNode, currentGroupNode, currentGroupNode.getChildCount());
3043                
3044                // Insert annotations
3045
Iterator JavaDoc<BugAnnotation> j = member.annotationIterator();
3046                while (j.hasNext()) {
3047                    BugAnnotation annotation = j.next();
3048                    DefaultMutableTreeNode JavaDoc annotationNode = new DefaultMutableTreeNode JavaDoc(annotation);
3049                    bugTreeModel.insertNodeInto(annotationNode, bugNode, bugNode.getChildCount());
3050                }
3051                
3052            }
3053        };
3054        
3055        // Create the grouper, and execute it to populate the bug tree
3056
Grouper<BugInstance> grouper = new Grouper<BugInstance>(callback);
3057        Comparator JavaDoc<BugInstance> groupComparator = getGroupComparator(groupBy);
3058        grouper.group(sortedCollection, groupComparator);
3059        
3060        // Let the tree know it needs to update itself
3061
bugTreeModel.nodeStructureChanged(bugRootNode);
3062        
3063        // Now we're done
3064
this.setCursor(orig);
3065    }
3066    
3067    /**
3068     * Get a BugInstance Comparator for given sort order.
3069     */

3070    private Comparator JavaDoc<BugInstance> getBugInstanceComparator(String JavaDoc sortOrder) {
3071        if (sortOrder.equals(GROUP_BY_CLASS))
3072            return bugInstanceByClassComparator;
3073        else if (sortOrder.equals(GROUP_BY_PACKAGE))
3074            return bugInstanceByPackageComparator;
3075        else if (sortOrder.equals(GROUP_BY_BUG_TYPE))
3076            return bugInstanceByTypeComparator;
3077                else if (sortOrder.equals(GROUP_BY_BUG_CATEGORY))
3078                        return bugInstanceByCategoryComparator;
3079        else
3080            throw new IllegalArgumentException JavaDoc("Bad sort order: " + sortOrder);
3081    }
3082    
3083    /**
3084     * Get a Grouper for a given sort order.
3085     */

3086    private Comparator JavaDoc<BugInstance> getGroupComparator(String JavaDoc groupBy) {
3087        if (groupBy.equals(GROUP_BY_CLASS)) {
3088            return bugInstanceClassComparator;
3089        } else if (groupBy.equals(GROUP_BY_PACKAGE)) {
3090            return bugInstancePackageComparator;
3091        } else if (groupBy.equals(GROUP_BY_BUG_TYPE)) {
3092            return bugInstanceTypeComparator;
3093        } else if (groupBy.equals(GROUP_BY_BUG_CATEGORY)) {
3094            return bugInstanceCategoryComparator;
3095        } else
3096            throw new IllegalArgumentException JavaDoc("Bad sort order: " + groupBy);
3097    }
3098    
3099    /**
3100     * Set the view panel to display the named view.
3101     */

3102    private void setView(String JavaDoc viewName) {
3103        //System.out.println("Showing view " + viewName);
3104
viewPanelLayout.show(viewPanel, viewName);
3105        boolean viewingBugs = viewName.equals("BugTree");
3106        if (viewingBugs)
3107            checkBugDetailsVisibility();
3108        
3109        viewProjectItem.setSelected(!viewingBugs);
3110        if (viewingBugs)
3111            viewBugsItem.setEnabled(true);
3112        viewBugsItem.setSelected(viewingBugs);
3113        
3114        currentView = viewName;
3115        ableEditMenu();
3116    }
3117    
3118    /**
3119     * Get which view is displayed currently.
3120     */

3121    private String JavaDoc getView() {
3122        return currentView;
3123    }
3124    
3125    /**
3126     * Called to add the jar file in the jarNameTextField to the
3127     * Jar file list (and the project it represents).
3128     */

3129    private void addJarToList() {
3130        String JavaDoc dirs = jarNameTextField.getText();
3131        String JavaDoc[] jarDirs = parsePaths(dirs);
3132        for (String JavaDoc jarFile : jarDirs) {
3133            if (!jarFile.equals("")) {
3134                addJarToProject(jarFile);
3135            }
3136        }
3137        jarNameTextField.setText("");
3138    }
3139    
3140    /**
3141     * Add a Src file to the current project.
3142     *
3143     * @param srcFile the jar file to add to the project
3144     */

3145    private void addSrcToProject(String JavaDoc srcFile) {
3146        Project project = getCurrentProject();
3147        if (project.addSourceDir(srcFile)) {
3148            DefaultListModel JavaDoc listModel = (DefaultListModel JavaDoc) sourceDirList.getModel();
3149            listModel.addElement(srcFile);
3150        }
3151    }
3152    
3153    /**
3154     * Add a Jar file to the current project.
3155     *
3156     * @param jarFile the jar file to add to the project
3157     */

3158    private void addJarToProject(String JavaDoc jarFile) {
3159        Project project = getCurrentProject();
3160        if (project.addFile(jarFile)) {
3161            DefaultListModel JavaDoc listModel = (DefaultListModel JavaDoc) jarFileList.getModel();
3162            listModel.addElement(jarFile);
3163        }
3164    }
3165    
3166    /**
3167     * Parses a classpath into it's sub paths
3168     *
3169     * @param path the classpath
3170     * @return an array of paths
3171     */

3172    private String JavaDoc[] parsePaths(String JavaDoc paths) {
3173        return paths.split(SystemProperties.getProperty("path.separator"));
3174    }
3175    
3176    /**
3177     * Called to add the source directory in the sourceDirTextField
3178     * to the source directory list (and the project it represents).
3179     */

3180    private void addSourceDirToList() {
3181        String JavaDoc dirs = srcDirTextField.getText();
3182        String JavaDoc[] sourceDirs = parsePaths(dirs);
3183        for (String JavaDoc sourceDir : sourceDirs) {
3184            if (!sourceDir.equals("")) {
3185                Project project = getCurrentProject();
3186                if (project.addSourceDir(sourceDir)) {
3187                    DefaultListModel JavaDoc listModel = (DefaultListModel JavaDoc) sourceDirList.getModel();
3188                    listModel.addElement(sourceDir);
3189                }
3190            }
3191        }
3192        srcDirTextField.setText("");
3193    }
3194    
3195    /**
3196     * Called to add the classpath entry in the classpathEntryTextField
3197     * to the classpath entry list (and the project it represents).
3198     */

3199    private void addClasspathEntryToList() {
3200        String JavaDoc dirs = classpathEntryTextField.getText();
3201        String JavaDoc[] classDirs = parsePaths(dirs);
3202        for (String JavaDoc classpathEntry : classDirs) {
3203            if (!classpathEntry.equals("")) {
3204                addClasspathEntryToProject(classpathEntry);
3205            }
3206        }
3207        classpathEntryTextField.setText("");
3208    }
3209    
3210    /**
3211     * Add a classpath entry to the current project.
3212     *
3213     * @param classpathEntry the classpath entry to add
3214     */

3215    private void addClasspathEntryToProject(String JavaDoc classpathEntry) {
3216        Project project = getCurrentProject();
3217        if (project.addAuxClasspathEntry(classpathEntry)) {
3218            DefaultListModel JavaDoc listModel = (DefaultListModel JavaDoc) classpathEntryList.getModel();
3219            listModel.addElement(classpathEntry);
3220        }
3221    }
3222    
3223    /**
3224     * Synchronize current bug instance with the bug detail
3225     * window (source view, details window, etc.)
3226     */

3227    private void synchBugInstance() {
3228        // Get current bug instance
3229
BugInstance selected = getCurrentBugInstance();
3230        if (selected == null)
3231            return;
3232        
3233        // If the details window is minimized, then the user can't see
3234
// it and there is no point in updating it.
3235
if (!viewBugDetailsItem.isSelected())
3236            return;
3237        
3238        // Get the current source line annotation.
3239
// If the current leaf selected is not a source line annotation,
3240
// or a method annotation containing a source line annotation.
3241
// use the default source line annotation from the current bug instance
3242
// (if any).
3243
JTree JavaDoc bugTree = getCurrentBugTree();
3244        
3245        // if the summary window is shown then skip it
3246
if (bugTree == null) {
3247            return;
3248        }
3249        SourceLineAnnotation srcLine = null;
3250        TreePath JavaDoc selPath = bugTree.getSelectionPath();
3251        if (selPath != null) {
3252            Object JavaDoc leaf = ((DefaultMutableTreeNode JavaDoc) selPath.getLastPathComponent()).getUserObject();
3253            if (leaf instanceof SourceLineAnnotation)
3254                srcLine = (SourceLineAnnotation) leaf;
3255            
3256            if (srcLine == null && leaf instanceof MethodAnnotation)
3257                srcLine = ((MethodAnnotation) leaf).getSourceLines();
3258            
3259            if (srcLine == null)
3260                srcLine = selected.getPrimarySourceLineAnnotation();
3261        }
3262        
3263        // Show source code.
3264
if (srcLine == null || srcLine != currentSourceLineAnnotation) {
3265            Project project = getCurrentProject();
3266            AnalysisRun analysisRun = getCurrentAnalysisRun();
3267            if (project == null) throw new IllegalStateException JavaDoc("null project!");
3268            if (analysisRun == null) throw new IllegalStateException JavaDoc("null analysis run!");
3269            try {
3270                boolean success = viewSource(project, analysisRun, srcLine);
3271                sourceTextArea.setEnabled(success);
3272                if (!success)
3273                    sourceTextArea.setText("No source line information for this bug");
3274            } catch (IOException JavaDoc e) {
3275                sourceTextArea.setText("Could not find source: " + e.getMessage());
3276                logger.logMessage(Logger.WARNING, e.getMessage());
3277            }
3278            
3279            currentSourceLineAnnotation = srcLine;
3280        }
3281        
3282        // Show bug info.
3283
showBugInfo(selected);
3284        
3285        // Synch annotation text.
3286
synchBugAnnotation(selected);
3287        
3288        // Now the bug details are up to date.
3289
currentBugInstance = selected;
3290    }
3291    
3292    private static final int SELECTION_VOFFSET = 2;
3293    
3294    /**
3295     * Update the source view window.
3296     *
3297     * @param project the project (containing the source directories to search)
3298     * @param analysisRun the analysis run (containing the mapping of classes to source files)
3299     * @param srcLine the source line annotation (specifying source file to load and
3300     * which lines to highlight)
3301     * @return true if the source was shown successfully, false otherwise
3302     */

3303    private boolean viewSource(Project project, AnalysisRun analysisRun, final SourceLineAnnotation srcLine)
3304    throws IOException JavaDoc {
3305        // Get rid of old source code text
3306
sourceTextArea.setText("");
3307        
3308        // There is nothing to do without a source annotation
3309
// TODO: actually, might want to put a message in the source window
3310
// explaining that we don't have the source file, and that
3311
// they might want to recompile with debugging info turned on.
3312
if (srcLine == null)
3313            return false;
3314        
3315        // Look up the source file for this class.
3316
sourceFinder.setSourceBaseList(project.getSourceDirList());
3317        String JavaDoc sourceFile;
3318        InputStream JavaDoc in;
3319        try {
3320            SourceFile source = sourceFinder.findSourceFile(srcLine);
3321            sourceFile = source.getFullFileName();
3322            in = source.getInputStream();
3323        } catch (IOException JavaDoc e) {
3324            logger.logMessage(Logger.WARNING, "No source file for class " + srcLine.getClassName());
3325            return false;
3326        }
3327        
3328        BufferedReader JavaDoc reader = null;
3329        
3330        try {
3331            reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(in));
3332            sourceTextArea.read(reader, sourceFile); // 2nd arg is mostly ignored
3333
} finally {
3334            if (reader != null)
3335                reader.close();
3336        }
3337        
3338        if (srcLine.isUnknown()) {
3339            // No line number information, so can't highlight anything
3340

3341            // There was code here to scroll to the top, but that isn't
3342
// needed because sourceTextArea.read() does that for us.
3343
return true;
3344        }
3345        
3346        // Highlight the annotation.
3347
// There seems to be some bug in Swing that sometimes prevents this code
3348
// from working when executed immediately after populating the
3349
// text in the text area. My guess is that when a large amount of text
3350
// is added, Swing defers some UI update work until "later" that is needed
3351
// to compute the visibility of text in the text area.
3352
// So, post some code to do the update to the Swing event queue.
3353
// Not really an ideal solution, but it seems to work.
3354
// note: Could reimplement this to use sourceTextArea.scrollRectToVisible(),
3355
// but if it ain't broke...
3356
SwingUtilities.invokeLater(new Runnable JavaDoc() {
3357            public void run() {
3358                // Highlight the lines from the source annotation.
3359
// Note that the source lines start at 1, while the line numbers
3360
// in the text area start at 0.
3361
try {
3362                    int startLine = srcLine.getStartLine() - 1;
3363                    int endLine = srcLine.getEndLine();
3364                    
3365                    // Compute number of rows visible.
3366
// What a colossal pain in the ass this is.
3367
// You'd think there would be a convenient method to
3368
// return this information, but no.
3369
JViewport JavaDoc viewport = sourceTextAreaScrollPane.getViewport();
3370                    Rectangle JavaDoc viewportRect = viewport.getViewRect();
3371                    int topRow = sourceTextArea.getLineOfOffset(sourceTextArea.viewToModel(viewportRect.getLocation()));
3372                    int bottomRow = sourceTextArea.getLineOfOffset(sourceTextArea.viewToModel(new Point JavaDoc(viewportRect.x, (viewportRect.y + viewportRect.height) - 1)));
3373                    int numRowsVisible = bottomRow - topRow;
3374                    
3375                    // Scroll the window so the beginning of the
3376
// annotation text will be (approximately) centered.
3377
int viewLine = Math.max(startLine - (numRowsVisible > 0 ? numRowsVisible / 2 : 0), 0);
3378                    int viewBegin = sourceTextArea.getLineStartOffset(viewLine);
3379                    Rectangle JavaDoc viewRect = sourceTextArea.modelToView(viewBegin);
3380                    viewport.setViewPosition(new Point JavaDoc(viewRect.x, viewRect.y));
3381                    
3382                    // Select (and highlight) the annotation.
3383
int selBegin = sourceTextArea.getLineStartOffset(startLine);
3384                    int selEnd = sourceTextArea.getLineStartOffset(endLine);
3385                    sourceTextArea.select(selBegin, selEnd);
3386                    sourceTextArea.getCaret().setSelectionVisible(true);
3387                } catch (javax.swing.text.BadLocationException JavaDoc e) {
3388                    logger.logMessage(Logger.ERROR, e.toString());
3389                }
3390            }
3391        });
3392        
3393        return true;
3394    }
3395    
3396    /**
3397     * Show descriptive text about the type of bug
3398     *
3399     * @param bugInstance the bug instance
3400     */

3401    private void showBugInfo(BugInstance bugInstance) {
3402        // Are we already showing details for this kind of bug?
3403
String JavaDoc bugDetailsKey = bugInstance.getType();
3404        if (bugDetailsKey.equals(currentBugDetailsKey))
3405            return;
3406        
3407        // Display the details
3408
String JavaDoc html = I18N.instance().getDetailHTML(bugDetailsKey);
3409        bugDescriptionEditorPane.setContentType("text/html");
3410        currentBugDetailsKey = bugDetailsKey;
3411        /*
3412        bugDescriptionEditorPane.setText(html);
3413        
3414        // : unfortunately, using setText() on the editor pane
3415        // results in the contents being scrolled to the bottom of the pane.
3416        // An immediate inline call to set the scroll position does nothing.
3417        // So, use invokeLater(), even though this results in flashing.
3418        // [What we really need is a way to set the text WITHOUT changing
3419        // the caret position. Need to investigate.]
3420        SwingUtilities.invokeLater(new Runnable() {
3421            public void run() {
3422                bugDescriptionScrollPane.getViewport().setViewPosition(new Point(0, 0));
3423            }
3424        });
3425        */

3426        StringReader JavaDoc reader = new StringReader JavaDoc(html); // no need for BufferedReader
3427
try {
3428            bugDescriptionEditorPane.read(reader, "html bug description");
3429        } catch (IOException JavaDoc e) {
3430            bugDescriptionEditorPane.setText("Could not find bug description: " + e.getMessage());
3431            logger.logMessage(Logger.WARNING, e.getMessage());
3432        } finally {
3433            reader.close(); // polite, but doesn't do much in StringReader
3434
}
3435    }
3436    
3437    /**
3438     * Synchronize the bug annotation text with the current bug instance,
3439     * and update the annotation text with the new bug instance.
3440     *
3441     * @param selected the new BugInstance
3442     */

3443    private void synchBugAnnotation(BugInstance selected) {
3444        if (currentBugInstance != null) {
3445            String JavaDoc text = annotationTextArea.getText();
3446            currentBugInstance.setAnnotationText(text);
3447        }
3448        
3449        //annotationTextArea.setText(selected.getAnnotationText());
3450
String JavaDoc userAnnotation = selected.getAnnotationText();
3451        if (userAnnotation==null || userAnnotation.length()==0) {
3452            // this is the common case, so might as well optimize it
3453
annotationTextArea.setText("");
3454            return;
3455        }
3456        StringReader JavaDoc reader = new StringReader JavaDoc(userAnnotation); // no need for BufferedReader
3457
try {
3458            annotationTextArea.read(reader, "user annotation");
3459        } catch (IOException JavaDoc e) {
3460            annotationTextArea.setText("Could not find user annotation: " + e.getMessage());
3461            logger.logMessage(Logger.WARNING, e.getMessage());
3462        } finally {
3463            reader.close(); // polite, but doesn't do much in StringReader
3464
}
3465    }
3466    
3467    /**
3468     * Toggle a bug category checkbox.
3469     * Changes are reflected in the displayed bug trees (if any)
3470     * and also in the user preferences.
3471     *
3472     * @param checkBox the bug category checkbox
3473     */

3474    private void toggleBugCategory(JCheckBoxMenuItem JavaDoc checkBox) {
3475        int index = 0;
3476        
3477        while (index < bugCategoryCheckBoxList.length) {
3478            if (bugCategoryCheckBoxList[index] == checkBox)
3479                break;
3480            ++index;
3481        }
3482        
3483        if (index == bugCategoryCheckBoxList.length) {
3484            error("Could not find bug category checkbox");
3485            return;
3486        }
3487        
3488        boolean selected = checkBox.isSelected();
3489        String JavaDoc bugCategory = bugCategoryList[index];
3490        
3491        if (selected) {
3492            getFilterSettings().addCategory(bugCategory);
3493        } else {
3494            getFilterSettings().removeCategory(bugCategory);
3495        }
3496        
3497        if (currentAnalysisRun != null) {
3498            synchAnalysisRun(currentAnalysisRun);
3499        }
3500    }
3501    
3502    /* ----------------------------------------------------------------------
3503     * Misc. helpers
3504     * ---------------------------------------------------------------------- */

3505    
3506    /**
3507     * Show About
3508     */

3509    void about() {
3510        AboutDialog dialog = new AboutDialog(this, logger, true);
3511        dialog.setSize(600, 554);
3512        dialog.setLocationRelativeTo(null); // center the dialog
3513
dialog.setVisible(true);
3514    }
3515    
3516    /**
3517     * Exit the application.
3518     */

3519    @SuppressWarnings JavaDoc("DM_EXIT")
3520    void exitFindBugs() {
3521        // TODO: offer to save work, etc.
3522
// UserPreferences.getUserPreferences().storeUserDetectorPreferences();
3523
UserPreferences.getUserPreferences().write();
3524        System.exit(0);
3525    }
3526    
3527    /**
3528     * Create a file chooser dialog.
3529     * Ensures that the dialog will start in the current directory.
3530     *
3531     * @return the file chooser
3532     */

3533    private JFileChooser JavaDoc createFileChooser() {
3534        return new JFileChooser JavaDoc(currentDirectory);
3535    }
3536    
3537    /**
3538     * Create a file chooser dialog.
3539     * Ensures that the dialog will start in the current directory.
3540     *
3541     * @param extraComp The extra component to append to the dialog
3542     * @return the file chooser
3543     */

3544    private JFileChooser JavaDoc createFileChooser(final JComponent JavaDoc extraComp) {
3545        return new JFileChooser JavaDoc(currentDirectory) {
3546            private static final long serialVersionUID = 1L;
3547
3548            @Override JavaDoc
3549            protected JDialog JavaDoc createDialog(Component JavaDoc parent) throws HeadlessException JavaDoc {
3550                JDialog JavaDoc dialog = super.createDialog(parent);
3551                dialog.getContentPane().add(extraComp, BorderLayout.SOUTH);
3552                dialog.setLocation(300, 200);
3553                dialog.setResizable(false);
3554                return dialog;
3555            }
3556        };
3557    }
3558    
3559    /**
3560     * Run a file chooser dialog.
3561     * If a file is chosen, then the current directory is updated.
3562     *
3563     * @param dialog the file chooser dialog
3564     * @param dialogTitle the dialog title
3565     * @return the outcome
3566     */

3567    private int chooseFile(JFileChooser JavaDoc dialog, String JavaDoc dialogTitle) {
3568        int outcome = dialog.showDialog(this, dialogTitle);
3569        return updateCurrentDirectoryFromDialog(dialog, outcome);
3570    }
3571    
3572    /**
3573     * Run a file chooser dialog to choose a file to open.
3574     * If a file is chosen, then the current directory is updated.
3575     *
3576     * @param dialog the file chooser dialog
3577     * @return the outcome
3578     */

3579    private int chooseFileToOpen(JFileChooser JavaDoc dialog) {
3580        int outcome = dialog.showOpenDialog(this);
3581        return updateCurrentDirectoryFromDialog(dialog, outcome);
3582    }
3583    
3584    private int updateCurrentDirectoryFromDialog(JFileChooser JavaDoc dialog, int outcome) {
3585        if (outcome != JFileChooser.CANCEL_OPTION) {
3586            File JavaDoc selectedFile = dialog.getSelectedFile();
3587            currentDirectory = selectedFile.getParentFile();
3588        }
3589        return outcome;
3590    }
3591    
3592    /**
3593     * Get the Logger.
3594     */

3595    public Logger getLogger() {
3596        return logger;
3597    }
3598    
3599    /**
3600     * Show an error dialog.
3601     */

3602    public void error(String JavaDoc message) {
3603        JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE);
3604    }
3605    
3606    /**
3607     * Write a message to the console window.
3608     *
3609     * @param message the message to write
3610     */

3611    public void writeToLog(String JavaDoc message) {
3612// consoleMessageArea.append(message);
3613
// consoleMessageArea.append("\n");
3614
}
3615    
3616    /**
3617     * Fix up the path that is received from JFileChooser, if necessary
3618     * Double clicking a directory causes a repeated name, for some reason
3619     * such as a:\b\c\c when a:\b\c was chosen
3620     */

3621    public File JavaDoc verifyFileSelection(File JavaDoc pickedFile) {
3622        if (pickedFile.exists())
3623            return pickedFile;
3624        
3625        File JavaDoc parent = pickedFile.getParentFile();
3626        if ((parent != null) && parent.getName().equals(pickedFile.getName()))
3627            return parent;
3628        
3629        //Something bad has happened
3630
return pickedFile;
3631    }
3632    
3633    /**
3634     * Get the current ProjectFilterSettings.
3635     */

3636    public ProjectFilterSettings getFilterSettings() {
3637        return UserPreferences.getUserPreferences().getFilterSettings();
3638    }
3639    
3640    /**
3641     * Get the current priority threshold.
3642     */

3643    public int getPriorityThreshold() {
3644        return getFilterSettings().getMinPriorityAsInt();
3645    }
3646    
3647    /**
3648     * Get list of AnalysisFeatureSettings.
3649     *
3650     * @return list of AnalysisFeatureSettings
3651     */

3652    public AnalysisFeatureSetting[] getSettingList() {
3653        return settingList;
3654    }
3655    
3656    /* ----------------------------------------------------------------------
3657     * main() method
3658     * ---------------------------------------------------------------------- */

3659    
3660    private static class SwingCommandLine extends FindBugsCommandLine {
3661        public SwingCommandLine() {
3662            addSwitch("-debug", "enable debug output");
3663            addSwitchWithOptionalExtraPart("-look", "plastic|gtk|native", "set look and feel");
3664            addOption("-project", "project file", "load given project");
3665            addOption("-loadbugs", "bugs xml filename", "load given bugs xml file");
3666        }
3667        
3668        String JavaDoc bugsFilename = "";
3669        
3670        public String JavaDoc getBugsFilename() {
3671            return bugsFilename;
3672        }
3673        
3674        //@Override
3675
@Override JavaDoc
3676        protected void handleOption(String JavaDoc option, String JavaDoc optionExtraPart) {
3677            if (option.equals("-debug")) {
3678                System.out.println("Setting findbugs.debug=true");
3679                System.setProperty("findbugs.debug", "true");
3680            } else if (option.equals("-look")) {
3681                String JavaDoc arg = optionExtraPart;
3682                
3683                String JavaDoc theme = null;
3684                if (arg.equals("plastic")) {
3685                    // You can get the Plastic look and feel from jgoodies.com:
3686
// http://www.jgoodies.com/downloads/libraries.html
3687
// Just put "plastic.jar" in the lib directory, right next
3688
// to the other jar files.
3689
theme = "com.jgoodies.plaf.plastic.PlasticXPLookAndFeel";
3690                } else if (arg.equals("gtk")) {
3691                    theme = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
3692                } else if (arg.equals("native")) {
3693                    theme = UIManager.getSystemLookAndFeelClassName();
3694                } else {
3695                    System.err.println("Style '" + arg + "' not supported");
3696                }
3697                
3698                if (theme != null) {
3699                    try {
3700                        UIManager.setLookAndFeel(theme);
3701                    } catch (Exception JavaDoc e) {
3702                        System.err.println("Couldn't load " + arg +
3703                                " look and feel: " + e.toString());
3704                    }
3705                }
3706            } else {
3707                super.handleOption(option, optionExtraPart);
3708            }
3709        }
3710        
3711        //@Override
3712
@Override JavaDoc
3713        protected void handleOptionWithArgument(String JavaDoc option, String JavaDoc argument) throws IOException JavaDoc {
3714            if (option.equals("-loadbugs")) {
3715                bugsFilename = argument;
3716            } else {
3717                super.handleOptionWithArgument(option, argument);
3718            }
3719        }
3720    }
3721    
3722    /**
3723     * Invoke from the command line.
3724     *
3725     * @param args the command line arguments
3726     * @throws IOException
3727     */

3728    public static void main(String JavaDoc args[]) throws IOException JavaDoc {
3729        Project project = null;
3730        
3731        SwingCommandLine commandLine = new SwingCommandLine();
3732        try {
3733            commandLine.parse(args);
3734        } catch (IllegalArgumentException JavaDoc e) {
3735            System.err.println("Error: " + e.getMessage());
3736            showSynopsis();
3737            ShowHelp.showGeneralOptions();
3738            showCommandLineOptions();
3739            System.exit(1);
3740        } catch (HelpRequestedException e) {
3741            showSynopsis();
3742            ShowHelp.showGeneralOptions();
3743            showCommandLineOptions();
3744            System.exit(1);
3745        }
3746        
3747        if (commandLine.getProject().getFileCount() > 0) {
3748            project = commandLine.getProject();
3749        }
3750        
3751        // Uncomment one of these to test I18N
3752
// Locale.setDefault( Locale.FRENCH );
3753
// Locale.setDefault( Locale.GERMAN );
3754
// Locale.setDefault( Locale.JAPANESE );
3755
// Locale.setDefault( new Locale( "et" ));
3756
// Locale.setDefault( new Locale( "fi" ));
3757
// Locale.setDefault( new Locale( "es" ));
3758
// Locale.setDefault( new Locale( "pl" ));
3759

3760        // Load plugins!
3761
DetectorFactoryCollection.instance();
3762        
3763        FindBugsFrame frame = new FindBugsFrame();
3764        
3765        if (project != null) {
3766            frame.setProject(project);
3767        } else if (commandLine.getBugsFilename().length() > 0) {
3768            try {
3769                File JavaDoc bugsFile = new File JavaDoc(commandLine.getBugsFilename());
3770                frame.loadBugsFromFile(bugsFile);
3771            } catch (Exception JavaDoc e) {
3772                System.err.println("Error: " + e.getMessage());
3773            }
3774        } else if (SystemProperties.getProperty("findbugs.loadBugsFromURL") != null) {
3775            // Allow JNLP launch to specify the URL of a report to load
3776
try {
3777                String JavaDoc urlspec = SystemProperties.getProperty("findbugs.loadBugsFromURL");
3778                frame.loadBugsFromURL(urlspec);
3779            } catch (Exception JavaDoc e) {
3780                System.err.println("Error: " + e.getMessage());
3781            }
3782        }
3783        
3784        if (commandLine.getSettingList() != null) {
3785            frame.settingList = commandLine.getSettingList();
3786            if (Arrays.equals(frame.settingList,FindBugs.MIN_EFFORT))
3787                frame.minEffortItem.setSelected(true);
3788            else if (Arrays.equals(frame.settingList, FindBugs.MAX_EFFORT))
3789                frame.maxEffortItem.setSelected(true);
3790        }
3791        
3792        frame.setSize(800, 600);
3793        frame.setLocationRelativeTo(null); // center the frame
3794
frame.setVisible(true);
3795    }
3796
3797    public static void showCommandLineOptions() {
3798        System.out.println("GUI options:");
3799        new SwingCommandLine().printUsage(System.out);
3800    }
3801
3802    public static void showSynopsis() {
3803        System.out.println("Usage: findbugs [general options] [gui options]");
3804    }
3805    
3806    /* ----------------------------------------------------------------------
3807     * Instance variables
3808     * ---------------------------------------------------------------------- */

3809    
3810    // Variables declaration - do not modify//GEN-BEGIN:variables
3811
private javax.swing.JMenuItem JavaDoc aboutItem;
3812    private javax.swing.JButton JavaDoc addClasspathEntryButton;
3813    private javax.swing.JButton JavaDoc addJarButton;
3814    private javax.swing.JButton JavaDoc addSourceDirButton;
3815    private javax.swing.JTextArea JavaDoc annotationTextArea;
3816    private javax.swing.JScrollPane JavaDoc annotationTextAreaScrollPane;
3817    private javax.swing.JButton JavaDoc browseClasspathEntryButton;
3818    private javax.swing.JButton JavaDoc browseJarButton;
3819    private javax.swing.JButton JavaDoc browseSrcDirButton;
3820    private javax.swing.JEditorPane JavaDoc bugDescriptionEditorPane;
3821    private javax.swing.JScrollPane JavaDoc bugDescriptionScrollPane;
3822    private javax.swing.JTabbedPane JavaDoc bugDetailsTabbedPane;
3823    private javax.swing.JEditorPane JavaDoc bugSummaryEditorPane;
3824    private javax.swing.JSplitPane JavaDoc bugTreeBugDetailsSplitter;
3825    private javax.swing.JPanel JavaDoc bugTreePanel;
3826    private javax.swing.JTree JavaDoc byBugCategoryBugTree;
3827    private javax.swing.JScrollPane JavaDoc byBugCategoryScrollPane;
3828    private javax.swing.JTree JavaDoc byBugTypeBugTree;
3829    private javax.swing.JScrollPane JavaDoc byBugTypeScrollPane;
3830    private javax.swing.JTree JavaDoc byClassBugTree;
3831    private javax.swing.JScrollPane JavaDoc byClassScrollPane;
3832    private javax.swing.JTree JavaDoc byPackageBugTree;
3833    private javax.swing.JScrollPane JavaDoc byPackageScrollPane;
3834    private javax.swing.JScrollPane JavaDoc bySummary;
3835    private javax.swing.JButton JavaDoc classpathDownButton;
3836    private javax.swing.JLabel JavaDoc classpathEntryLabel;
3837    private javax.swing.JList JavaDoc classpathEntryList;
3838    private javax.swing.JLabel JavaDoc classpathEntryListLabel;
3839    private javax.swing.JScrollPane JavaDoc classpathEntryListScrollPane;
3840    private javax.swing.JTextField JavaDoc classpathEntryTextField;
3841    private javax.swing.JButton JavaDoc classpathUpButton;
3842    private javax.swing.JMenuItem JavaDoc closeProjectItem;
3843    private javax.swing.JMenuItem JavaDoc configureDetectorsItem;
3844    private javax.swing.JMenuItem JavaDoc copyItem;
3845    private javax.swing.JMenuItem JavaDoc cutItem;
3846    private javax.swing.JMenu JavaDoc editMenu;
3847    private javax.swing.JLabel JavaDoc editProjectLabel;
3848    private javax.swing.JPanel JavaDoc editProjectPanel;
3849    private javax.swing.ButtonGroup JavaDoc effortButtonGroup;
3850    private javax.swing.JMenu JavaDoc effortMenu;
3851    private javax.swing.JPanel JavaDoc emptyPanel;
3852    private javax.swing.JMenuItem JavaDoc exitItem;
3853    private javax.swing.JRadioButtonMenuItem JavaDoc expPriorityButton;
3854    private javax.swing.JMenu JavaDoc fileMenu;
3855    private javax.swing.JMenu JavaDoc filterWarningsMenu;
3856    private javax.swing.JButton JavaDoc findBugsButton;
3857    private javax.swing.JCheckBoxMenuItem JavaDoc fullDescriptionsItem;
3858    private javax.swing.JTabbedPane JavaDoc groupByTabbedPane;
3859    private javax.swing.JLabel JavaDoc growBoxSpacer;
3860    private javax.swing.JMenu JavaDoc helpMenu;
3861    private javax.swing.JRadioButtonMenuItem JavaDoc highPriorityButton;
3862    private javax.swing.JPanel JavaDoc jPanel1;
3863    private javax.swing.JSeparator JavaDoc jSeparator1;
3864    private javax.swing.JSeparator JavaDoc jSeparator10;
3865    private javax.swing.JSeparator JavaDoc jSeparator11;
3866    private javax.swing.JSeparator JavaDoc jSeparator2;
3867    private javax.swing.JSeparator JavaDoc jSeparator3;
3868    private javax.swing.JSeparator JavaDoc jSeparator4;
3869    private javax.swing.JSeparator JavaDoc jSeparator5;
3870    private javax.swing.JSeparator JavaDoc jSeparator6;
3871    private javax.swing.JSeparator JavaDoc jSeparator7;
3872    private javax.swing.JSeparator JavaDoc jSeparator8;
3873    private javax.swing.JSeparator JavaDoc jSeparator9;
3874    private javax.swing.JLabel JavaDoc jarFileLabel;
3875    private javax.swing.JList JavaDoc jarFileList;
3876    private javax.swing.JLabel JavaDoc jarFileListLabel;
3877    private javax.swing.JScrollPane JavaDoc jarFileListScrollPane;
3878    private javax.swing.JTextField JavaDoc jarNameTextField;
3879    private javax.swing.JMenuItem JavaDoc loadBugsItem;
3880    private javax.swing.JLabel JavaDoc logoLabel;
3881    private javax.swing.JRadioButtonMenuItem JavaDoc lowPriorityButton;
3882    private javax.swing.JCheckBoxMenuItem JavaDoc maxEffortItem;
3883    private javax.swing.JRadioButtonMenuItem JavaDoc mediumPriorityButton;
3884    private javax.swing.JCheckBoxMenuItem JavaDoc minEffortItem;
3885    private javax.swing.JMenuItem JavaDoc newProjectItem;
3886    private javax.swing.JCheckBoxMenuItem JavaDoc normalEffortItem;
3887    private javax.swing.JMenuItem JavaDoc openProjectItem;
3888    private javax.swing.JMenuItem JavaDoc pasteItem;
3889    private javax.swing.ButtonGroup JavaDoc priorityButtonGroup;
3890    private javax.swing.JMenu JavaDoc recentProjectsMenu;
3891    private javax.swing.JMenuItem JavaDoc reloadProjectItem;
3892    private javax.swing.JButton JavaDoc removeClasspathEntryButton;
3893    private javax.swing.JButton JavaDoc removeJarButton;
3894    private javax.swing.JButton JavaDoc removeSrcDirButton;
3895    private javax.swing.JPanel JavaDoc reportPanel;
3896    private javax.swing.JMenuItem JavaDoc saveBugsItem;
3897    private javax.swing.JMenuItem JavaDoc saveProjectAsItem;
3898    private javax.swing.JMenuItem JavaDoc saveProjectItem;
3899    private javax.swing.JMenuItem JavaDoc selectAllItem;
3900    private javax.swing.JMenu JavaDoc settingsMenu;
3901    private javax.swing.JLabel JavaDoc sourceDirLabel;
3902    private javax.swing.JList JavaDoc sourceDirList;
3903    private javax.swing.JLabel JavaDoc sourceDirListLabel;
3904    private javax.swing.JScrollPane JavaDoc sourceDirListScrollPane;
3905    private javax.swing.JButton JavaDoc sourceDownButton;
3906    private javax.swing.JTextArea JavaDoc sourceTextArea;
3907    private LineNumberer sourceLineNumberer;
3908    private javax.swing.JScrollPane JavaDoc sourceTextAreaScrollPane;
3909    private javax.swing.JButton JavaDoc sourceUpButton;
3910    private javax.swing.JTextField JavaDoc srcDirTextField;
3911    private javax.swing.JMenuBar JavaDoc theMenuBar;
3912    private javax.swing.JLabel JavaDoc urlLabel;
3913    private javax.swing.JCheckBoxMenuItem JavaDoc viewBugDetailsItem;
3914    private javax.swing.JRadioButtonMenuItem JavaDoc viewBugsItem;
3915    private javax.swing.JMenu JavaDoc viewMenu;
3916    private javax.swing.JPanel JavaDoc viewPanel;
3917    private javax.swing.JRadioButtonMenuItem JavaDoc viewProjectItem;
3918    // End of variables declaration//GEN-END:variables
3919

3920    // My variable declarations
3921
private Logger logger;
3922    private CardLayout JavaDoc viewPanelLayout;
3923    private String JavaDoc currentView;
3924    private File JavaDoc currentDirectory;
3925    private Project currentProject;
3926    private JTree JavaDoc[] bugTreeList;
3927    private AnalysisRun currentAnalysisRun;
3928    private SourceFinder sourceFinder = new SourceFinder();
3929    private BugInstance currentBugInstance; // be lazy in switching bug instance details
3930
private SourceLineAnnotation currentSourceLineAnnotation; // as above
3931
private String JavaDoc currentBugDetailsKey;
3932    private JCheckBoxMenuItem JavaDoc[] bugCategoryCheckBoxList;
3933    private String JavaDoc[] bugCategoryList;
3934    private AnalysisFeatureSetting[] settingList = FindBugs.DEFAULT_EFFORT;
3935
3936    // My constant declarations
3937
private final static boolean MAC_OS_X = SystemProperties.getProperty("os.name").toLowerCase().startsWith("mac os x");
3938
3939    private static int getMenuMask() {
3940        return Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
3941    }
3942
3943}
3944
Popular Tags