KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jdepend > swingui > JDepend


1 package jdepend.swingui;
2
3 import java.awt.*;
4 import java.awt.event.*;
5 import java.io.*;
6 import java.util.*;
7 import javax.swing.*;
8 import javax.swing.border.*;
9 import javax.swing.event.*;
10 import javax.swing.tree.*;
11
12 import jdepend.framework.JavaClass;
13 import jdepend.framework.JavaPackage;
14 import jdepend.framework.PackageComparator;
15 import jdepend.framework.PackageFilter;
16 import jdepend.framework.ParserListener;
17
18 /**
19  * The <code>JDepend</code> class analyzes directories of Java class files,
20  * generates metrics for each Java package, and reports the metrics in a Swing
21  * tree.
22  *
23  * @author <b>Mike Clark</b>
24  * @author Clarkware Consulting, Inc.
25  */

26
27 public class JDepend implements ParserListener {
28
29     private jdepend.framework.JDepend analyzer;
30
31     private JFrame frame;
32
33     private StatusPanel statusPanel;
34
35     private JTextField statusField;
36
37     private JProgressBar progressBar;
38
39     private DependTree afferentTree;
40
41     private DependTree efferentTree;
42
43     private Hashtable resourceStrings;
44
45     private Hashtable actions;
46
47     private static Font BOLD_FONT = new Font("dialog", Font.BOLD, 12);
48
49     /**
50      * Constructs a <code>JDepend</code> instance.
51      */

52     public JDepend() {
53
54         analyzer = new jdepend.framework.JDepend();
55
56         analyzer.addParseListener(this);
57
58         //
59
// Force the cross platform L&F.
60
//
61
try {
62             UIManager.setLookAndFeel(UIManager
63                     .getCrossPlatformLookAndFeelClassName());
64             //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
65
} catch (Exception JavaDoc e) {
66             e.printStackTrace();
67         }
68
69         //
70
// Install the resource string table.
71
//
72
resourceStrings = new Hashtable();
73         resourceStrings.put("menubar", "File");
74         resourceStrings.put("File", "About Exit");
75
76         //
77
// Install the action table.
78
//
79
actions = new Hashtable();
80         actions.put("About", new AboutAction());
81         actions.put("Exit", new ExitAction());
82     }
83
84     /**
85      * Adds the specified directory name to the collection of directories to be
86      * analyzed.
87      *
88      * @param name Directory name.
89      * @throws IOException If the directory does not exist.
90      */

91     public void addDirectory(String JavaDoc name) throws IOException {
92         analyzer.addDirectory(name);
93     }
94
95     /**
96      * Sets the package filter.
97      *
98      * @param filter Package filter.
99      */

100     public void setFilter(PackageFilter filter) {
101         analyzer.setFilter(filter);
102     }
103
104     /**
105      * Sets the comma-separated list of components.
106      */

107     public void setComponents(String JavaDoc components) {
108         analyzer.setComponents(components);
109     }
110     
111     /**
112      * Analyzes the registered directories, generates metrics for each Java
113      * package, and reports the metrics in a graphical format.
114      */

115     public void analyze() {
116
117         display();
118
119         startProgressMonitor(analyzer.countClasses());
120
121         ArrayList packages = new ArrayList(analyzer.analyze());
122
123         Collections.sort(packages, new PackageComparator(PackageComparator
124                 .byName()));
125
126         stopProgressMonitor();
127
128         updateTree(packages);
129     }
130
131     /**
132      * Called whenever a Java source file is parsed into the specified
133      * <code>JavaClass</code> instance.
134      *
135      * @param jClass Parsed Java class.
136      */

137     public void onParsedJavaClass(final JavaClass jClass) {
138         SwingUtilities.invokeLater(new Runnable JavaDoc() {
139
140             public void run() {
141                 getProgressBar().setValue(getProgressBar().getValue() + 1);
142             }
143         });
144     }
145
146     private void display() {
147         frame = createUI();
148         frame.setVisible(true);
149     }
150
151     private void updateTree(ArrayList packages) {
152
153         JavaPackage jPackage = new JavaPackage("root");
154         jPackage.setAfferents(packages);
155         jPackage.setEfferents(packages);
156
157         AfferentNode ah = new AfferentNode(null, jPackage);
158         getAfferentTree().setModel(new DependTreeModel(ah));
159
160         EfferentNode eh = new EfferentNode(null, jPackage);
161         getEfferentTree().setModel(new DependTreeModel(eh));
162     }
163
164     private void startProgressMonitor(final int maxValue) {
165         SwingUtilities.invokeLater(new Runnable JavaDoc() {
166
167             public void run() {
168                 getProgressBar().setMinimum(0);
169                 getProgressBar().setMaximum(maxValue);
170                 getStatusPanel().setStatusComponent(getProgressBar());
171             }
172         });
173     }
174
175     private void stopProgressMonitor() {
176         SwingUtilities.invokeLater(new Runnable JavaDoc() {
177
178             public void run() {
179                 getStatusPanel().setStatusComponent(getStatusField());
180                 int classCount = analyzer.countClasses();
181                 int packageCount = analyzer.countPackages();
182                 showStatusMessage("Analyzed " + packageCount + " packages ("
183                         + classCount + " classes).");
184             }
185         });
186     }
187
188     private JFrame createUI() {
189
190         JFrame frame = createFrame("JDepend");
191
192         JMenuBar menuBar = createMenubar();
193         frame.setJMenuBar(menuBar);
194
195         JPanel treePanel = createTreePanel();
196         StatusPanel statusPanel = getStatusPanel();
197
198         frame.getContentPane().add("Center", treePanel);
199         frame.getContentPane().add("South", statusPanel);
200         frame.pack();
201
202         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
203         int width = 700;
204         int height = 500;
205         int x = (screenSize.width - width) / 2;
206         int y = (screenSize.height - height) / 2;
207         frame.setBounds(x, y, width, height);
208         frame.setSize(width, height);
209
210         return frame;
211     }
212
213     private JFrame createFrame(String JavaDoc title) {
214
215         JFrame frame = new JFrame(title);
216
217         frame.getContentPane().setLayout(new BorderLayout());
218         frame.setBackground(SystemColor.control);
219
220         frame.addWindowListener(new WindowAdapter() {
221
222             public void windowClosing(WindowEvent e) {
223                 new ExitAction().actionPerformed(null);
224             }
225         });
226
227         return frame;
228     }
229
230     private JPanel createTreePanel() {
231
232         JPanel panel = new JPanel();
233
234         panel.setLayout(new GridLayout(2, 1));
235         panel.add(getEfferentTree());
236         panel.add(getAfferentTree());
237
238         /*
239          * panel.setLayout(new GridLayout(1,1)); JSplitPane splitPane = new
240          * JSplitPane(JSplitPane.VERTICAL_SPLIT);
241          * splitPane.setOneTouchExpandable(true);
242          * splitPane.setTopComponent(getEfferentTree());
243          * splitPane.setBottomComponent(getAfferentTree());
244          * panel.add(splitPane);
245          */

246
247         return panel;
248     }
249
250     private StatusPanel createStatusPanel() {
251         StatusPanel panel = new StatusPanel();
252         panel.setStatusComponent(getStatusField());
253
254         return panel;
255     }
256
257     private JProgressBar createProgressBar() {
258         JProgressBar bar = new JProgressBar();
259         bar.setStringPainted(true);
260
261         return bar;
262     }
263
264     private JTextField createStatusField() {
265         JTextField statusField = new JTextField();
266         statusField.setFont(BOLD_FONT);
267         statusField.setEditable(false);
268         statusField.setForeground(Color.black);
269         statusField.setBorder(BorderFactory
270                 .createBevelBorder(BevelBorder.LOWERED));
271
272         Insets insets = new Insets(5, 5, 5, 5);
273         statusField.setMargin(insets);
274
275         return statusField;
276     }
277
278     private JMenuBar createMenubar() {
279
280         JMenuBar menuBar = new JMenuBar();
281
282         String JavaDoc[] menuKeys = tokenize((String JavaDoc) resourceStrings.get("menubar"));
283         for (int i = 0; i < menuKeys.length; i++) {
284             JMenu m = createMenu(menuKeys[i]);
285             if (m != null) {
286                 menuBar.add(m);
287             }
288         }
289
290         return menuBar;
291     }
292
293     private JMenu createMenu(String JavaDoc key) {
294
295         String JavaDoc[] itemKeys = tokenize((String JavaDoc) resourceStrings.get(key));
296         JMenu menu = new JMenu(key);
297         for (int i = 0; i < itemKeys.length; i++) {
298             if (itemKeys[i].equals("-")) {
299                 menu.addSeparator();
300             } else {
301                 JMenuItem mi = createMenuItem(itemKeys[i]);
302                 menu.add(mi);
303             }
304         }
305
306         char mnemonic = key.charAt(0);
307         menu.setMnemonic(mnemonic);
308
309         return menu;
310     }
311
312     private JMenuItem createMenuItem(String JavaDoc key) {
313
314         JMenuItem mi = new JMenuItem(key);
315
316         char mnemonic = key.charAt(0);
317         mi.setMnemonic(mnemonic);
318
319         char accelerator = key.charAt(0);
320         mi.setAccelerator(KeyStroke.getKeyStroke(accelerator,
321                 java.awt.Event.CTRL_MASK));
322
323         String JavaDoc actionString = key;
324         mi.setActionCommand(actionString);
325
326         Action a = getActionForCommand(actionString);
327         if (a != null) {
328             mi.addActionListener(a);
329             mi.setEnabled(a.isEnabled());
330         } else {
331             mi.setEnabled(false);
332         }
333
334         return mi;
335     }
336
337     private void showStatusMessage(final String JavaDoc message) {
338         getStatusField().setFont(BOLD_FONT);
339         getStatusField().setForeground(Color.black);
340         getStatusField().setText(" " + message);
341     }
342
343     private void showStatusError(final String JavaDoc message) {
344         getStatusField().setFont(BOLD_FONT);
345         getStatusField().setForeground(Color.red);
346         getStatusField().setText(" " + message);
347     }
348
349     private DependTree getAfferentTree() {
350         if (afferentTree == null) {
351             afferentTree = new DependTree();
352             afferentTree.addTreeSelectionListener(new TreeListener());
353         }
354
355         return afferentTree;
356     }
357
358     private DependTree getEfferentTree() {
359         if (efferentTree == null) {
360             efferentTree = new DependTree();
361             efferentTree.addTreeSelectionListener(new TreeListener());
362         }
363
364         return efferentTree;
365     }
366
367     private StatusPanel getStatusPanel() {
368         if (statusPanel == null) {
369             statusPanel = createStatusPanel();
370         }
371         return statusPanel;
372     }
373
374     private JProgressBar getProgressBar() {
375         if (progressBar == null) {
376             progressBar = createProgressBar();
377         }
378
379         return progressBar;
380     }
381
382     private JTextField getStatusField() {
383         if (statusField == null) {
384             statusField = createStatusField();
385         }
386         return statusField;
387     }
388
389     private Action getActionForCommand(String JavaDoc command) {
390         return (Action) actions.get(command);
391     }
392
393     /*
394      * Parses the specified string into an array of strings on whitespace
395      * boundaries. @param input String to tokenize. @return Strings.
396      */

397     private String JavaDoc[] tokenize(String JavaDoc input) {
398
399         Vector v = new Vector();
400         StringTokenizer t = new StringTokenizer(input);
401
402         while (t.hasMoreTokens()) {
403             v.addElement(t.nextToken());
404         }
405
406         String JavaDoc cmd[] = new String JavaDoc[v.size()];
407         for (int i = 0; i < cmd.length; i++) {
408             cmd[i] = (String JavaDoc) v.elementAt(i);
409         }
410
411         return cmd;
412     }
413
414     private void postStatusMessage(final String JavaDoc message) {
415         SwingUtilities.invokeLater(new Runnable JavaDoc() {
416
417             public void run() {
418                 showStatusMessage(message);
419             }
420         });
421     }
422
423     private void postStatusError(final String JavaDoc message) {
424         SwingUtilities.invokeLater(new Runnable JavaDoc() {
425
426             public void run() {
427                 showStatusError(message);
428             }
429         });
430     }
431
432     //
433
// Tree selection handler.
434
//
435
private class TreeListener implements TreeSelectionListener {
436
437         /**
438          * Constructs a <code>TreeListener</code> instance.
439          */

440         TreeListener() {
441         }
442
443         /**
444          * Callback method triggered whenever the value of the tree selection
445          * changes.
446          *
447          * @param te Event that characterizes the change.
448          */

449         public void valueChanged(TreeSelectionEvent te) {
450
451             TreePath path = te.getNewLeadSelectionPath();
452
453             if (path != null) {
454                 PackageNode node = (PackageNode) path.getLastPathComponent();
455                 showStatusMessage(node.toMetricsString());
456             }
457         }
458     }
459
460     //
461
// About action handler.
462
//
463
private class AboutAction extends AbstractAction {
464
465         /**
466          * Constructs an <code>AboutAction</code> instance.
467          */

468         AboutAction() {
469             super("About");
470         }
471
472         /**
473          * Handles the action.
474          */

475         public void actionPerformed(ActionEvent e) {
476             AboutDialog d = new AboutDialog(frame);
477             d.setModal(true);
478             d.setLocation(300, 300);
479             d.show();
480         }
481     }
482
483     //
484
// Exit action handler.
485
//
486
private class ExitAction extends AbstractAction {
487
488         /**
489          * Constructs an <code>ExitAction</code> instance.
490          */

491         ExitAction() {
492             super("Exit");
493         }
494
495         /**
496          * Handles the action.
497          */

498         public void actionPerformed(ActionEvent e) {
499             frame.dispose();
500             System.exit(0);
501         }
502     }
503
504     private void usage(String JavaDoc message) {
505         if (message != null) {
506             System.err.println("\n" + message);
507         }
508
509         String JavaDoc baseUsage = "\nJDepend ";
510
511         System.err.println("");
512         System.err.println("usage: ");
513         System.err.println(baseUsage + "-components <components> " +
514             "<directory> [directory2 [directory 3] ...]");
515         System.exit(1);
516     }
517
518     private void instanceMain(String JavaDoc[] args) {
519
520         if (args.length < 1) {
521             usage("Must specify at least one directory.");
522         }
523
524         int directoryCount = 0;
525
526         for (int i = 0; i < args.length; i++) {
527             if (args[i].startsWith("-")) {
528                 if (args[i].equalsIgnoreCase("-components")) {
529                     if (args.length <= i + 1) {
530                         usage("Components not specified.");
531                     }
532                     setComponents(args[++i]);
533                 } else {
534                     usage("Invalid argument: " + args[i]);
535                 }
536             } else {
537                 try {
538                     addDirectory(args[i]);
539                     directoryCount++;
540                 } catch (IOException ioe) {
541                     usage("Directory does not exist: " + args[i]);
542                 }
543             }
544         }
545         
546         if (directoryCount == 0) {
547             usage("Must specify at least one directory.");
548         }
549
550         analyze();
551         
552         for (int i = 0; i < args.length; i++) {
553
554             if (args[i].startsWith("-")) {
555                 usage("Invalid argument: " + args[i]);
556             }
557
558             try {
559
560                 addDirectory(args[i]);
561                 directoryCount++;
562
563             } catch (IOException ioe) {
564                 usage("Directory does not exist: " + args[i]);
565             }
566         }
567
568         if (directoryCount == 0) {
569             usage("Must specify at least one directory.");
570         }
571
572         analyze();
573     }
574
575     public static void main(String JavaDoc[] args) {
576         new JDepend().instanceMain(args);
577     }
578 }
579
580
Popular Tags