001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.dependencyfinder.gui;
034:
035: import java.awt.*;
036: import java.awt.event.*;
037: import java.io.*;
038: import javax.swing.*;
039: import javax.swing.border.*;
040: import javax.swing.table.*;
041: import javax.swing.text.*;
042:
043: import com.jeantessier.commandline.*;
044: import com.jeantessier.metrics.*;
045: import org.apache.log4j.*;
046:
047: public class OOMetrics extends JFrame {
048: private static final TableCellRenderer RENDERER = new MeasurementTableCellRenderer();
049:
050: private MetricsFactory factory;
051:
052: private JMenuBar menuBar = new JMenuBar();
053: private JMenu fileMenu = new JMenu();
054: private JMenu helpMenu = new JMenu();
055: private JToolBar toolbar = new JToolBar();
056: private JTextArea projectArea = new JTextArea();
057: private JButton filterButton = new JButton("Filter:");
058: private JTextField filterField = new JTextField("//");
059: private StatusLine statusLine = new StatusLine(420);
060: private JProgressBar progressBar = new JProgressBar();
061:
062: private OOMetricsTableModel groupsModel;
063: private OOMetricsTableModel classesModel;
064: private OOMetricsTableModel methodsModel;
065:
066: private File inputFile = new File(".");
067:
068: public OOMetrics(MetricsFactory factory) {
069: this .factory = factory;
070:
071: this .setSize(new Dimension(800, 600));
072: this .setTitle("OO Metrics");
073: this .setIconImage(new ImageIcon(getClass().getResource(
074: "icons/logoicon.gif")).getImage());
075: this .setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
076: this .addWindowListener(new WindowKiller());
077:
078: groupsModel = new OOMetricsTableModel(factory
079: .getConfiguration().getGroupMeasurements());
080: classesModel = new OOMetricsTableModel(factory
081: .getConfiguration().getClassMeasurements());
082: methodsModel = new OOMetricsTableModel(factory
083: .getConfiguration().getMethodMeasurements());
084:
085: buildMenus();
086: buildUI();
087:
088: try {
089: UIManager
090: .setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
091: SwingUtilities.updateComponentTreeUI(this );
092: } catch (Exception ex) {
093: Logger.getLogger(OOMetrics.class).error(
094: "Unable to set look and feel", ex);
095: }
096:
097: statusLine.showInfo("Ready.");
098: }
099:
100: MetricsFactory getMetricsFactory() {
101: return factory;
102: }
103:
104: void setMetricsFactory(MetricsFactory factory) {
105: this .factory = factory;
106: }
107:
108: JTextArea getProjectArea() {
109: return projectArea;
110: }
111:
112: OOMetricsTableModel getGroupsModel() {
113: return groupsModel;
114: }
115:
116: OOMetricsTableModel getClassesModel() {
117: return classesModel;
118: }
119:
120: OOMetricsTableModel getMethodsModel() {
121: return methodsModel;
122: }
123:
124: File getInputFile() {
125: return inputFile;
126: }
127:
128: void setInputFile(File inputFile) {
129: this .inputFile = inputFile;
130: }
131:
132: JTextComponent getFilterField() {
133: return filterField;
134: }
135:
136: StatusLine getStatusLine() {
137: return statusLine;
138: }
139:
140: JProgressBar getProgressBar() {
141: return progressBar;
142: }
143:
144: private void buildMenus() {
145: buildFileMenu();
146: buildHelpMenu();
147:
148: this .setJMenuBar(menuBar);
149: }
150:
151: private void buildFileMenu() {
152: menuBar.add(fileMenu);
153:
154: fileMenu.setText("File");
155:
156: Action action;
157: JMenuItem menuItem;
158: JButton button;
159:
160: action = new MetricsExtractAction(this );
161: menuItem = fileMenu.add(action);
162: menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E,
163: Event.CTRL_MASK));
164: menuItem.setMnemonic('e');
165: button = toolbar.add(action);
166: button.setToolTipText((String) action
167: .getValue(Action.LONG_DESCRIPTION));
168:
169: toolbar.addSeparator();
170: fileMenu.addSeparator();
171:
172: action = new NewMetricsAction(this );
173: menuItem = fileMenu.add(action);
174: menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
175: Event.CTRL_MASK));
176: menuItem.setMnemonic('n');
177: button = toolbar.add(action);
178: button.setToolTipText((String) action
179: .getValue(Action.LONG_DESCRIPTION));
180:
181: toolbar.addSeparator();
182: fileMenu.addSeparator();
183:
184: action = new ExitAction(this );
185: menuItem = fileMenu.add(action);
186: menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
187: Event.CTRL_MASK));
188: menuItem.setMnemonic('x');
189:
190: this .setJMenuBar(menuBar);
191: }
192:
193: private void buildHelpMenu() {
194: menuBar.add(helpMenu);
195:
196: helpMenu.setText("Help");
197:
198: Action action;
199: JMenuItem menuItem;
200:
201: action = new AboutAction(this );
202: menuItem = helpMenu.add(action);
203: menuItem.setMnemonic('a');
204: }
205:
206: private void buildUI() {
207: this .getContentPane().setLayout(new BorderLayout());
208: this .getContentPane().add(buildControlPanel(),
209: BorderLayout.NORTH);
210: this .getContentPane().add(buildResultPanel(),
211: BorderLayout.CENTER);
212: this .getContentPane().add(buildStatusPanel(),
213: BorderLayout.SOUTH);
214: }
215:
216: private JComponent buildControlPanel() {
217: return toolbar;
218: }
219:
220: private JComponent buildResultPanel() {
221: JPanel result = new JPanel();
222:
223: result.setLayout(new BorderLayout());
224: result.add(new JSplitPane(JSplitPane.VERTICAL_SPLIT,
225: buildProjectPanel(), buildChartsPanel()),
226: BorderLayout.CENTER);
227: result.add(buildFilterPanel(), BorderLayout.SOUTH);
228:
229: return result;
230: }
231:
232: private JComponent buildProjectPanel() {
233: JComponent result = new JScrollPane(projectArea);
234:
235: projectArea.setEditable(false);
236:
237: return result;
238: }
239:
240: private JComponent buildChartsPanel() {
241: JTabbedPane result = new JTabbedPane();
242:
243: // result.setBorder(BorderFactory.createTitledBorder("Data"));
244: result.addTab("Groups", buildGroupsChartPanel());
245: result.addTab("Classes", buildClassesChartPanel());
246: result.addTab("Methods", buildMethodsChartPanel());
247:
248: return result;
249: }
250:
251: private JComponent buildGroupsChartPanel() {
252: return buildChartPanel(getGroupsModel());
253: }
254:
255: private JComponent buildClassesChartPanel() {
256: return buildChartPanel(getClassesModel());
257: }
258:
259: private JComponent buildMethodsChartPanel() {
260: return buildChartPanel(getMethodsModel());
261: }
262:
263: private JComponent buildChartPanel(OOMetricsTableModel model) {
264: JComponent result;
265:
266: JTable table = new JTable(model);
267:
268: table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
269: table.setRowSelectionAllowed(true);
270: table.setDefaultRenderer(Object.class, RENDERER);
271: table.setShowHorizontalLines(false);
272: table.setShowVerticalLines(false);
273: TableHeaderListener listener = new TableHeaderListener(table,
274: model);
275: table.getTableHeader().addMouseListener(listener);
276: table.getTableHeader().addMouseMotionListener(listener);
277:
278: result = new JScrollPane(table);
279:
280: return result;
281: }
282:
283: private JComponent buildFilterPanel() {
284: JPanel result = new JPanel();
285:
286: result.setLayout(new BorderLayout());
287: result.add(filterButton, BorderLayout.WEST);
288: result.add(filterField, BorderLayout.CENTER);
289:
290: filterButton.addActionListener(new FilterActionListener(this ));
291:
292: return result;
293: }
294:
295: private JComponent buildStatusPanel() {
296: JPanel result = new JPanel();
297:
298: Dimension size = getProgressBar().getPreferredSize();
299: size.width = 100;
300: getProgressBar().setPreferredSize(size);
301: getProgressBar().setBorder(
302: BorderFactory.createBevelBorder(BevelBorder.LOWERED));
303:
304: result.setLayout(new BorderLayout());
305: result.add(getStatusLine(), BorderLayout.CENTER);
306: result.add(getProgressBar(), BorderLayout.EAST);
307:
308: return result;
309: }
310:
311: public static void showError(CommandLineUsage clu, String msg) {
312: System.err.println(msg);
313: showError(clu);
314: }
315:
316: public static void showError(CommandLineUsage clu) {
317: System.err.println(clu);
318: }
319:
320: public static void main(String[] args) throws Exception {
321: // Parsing the command line
322: CommandLine commandLine = new CommandLine(
323: new NullParameterStrategy());
324: commandLine.addSingleValueSwitch("default-configuration", true);
325: commandLine.addSingleValueSwitch("configuration");
326: commandLine.addToggleSwitch("validate");
327: commandLine.addToggleSwitch("help");
328:
329: CommandLineUsage usage = new CommandLineUsage("OOMetrics");
330: commandLine.accept(usage);
331:
332: try {
333: commandLine.parse(args);
334: } catch (IllegalArgumentException ex) {
335: showError(usage, ex.toString());
336: System.exit(1);
337: }
338:
339: if (commandLine.getToggleSwitch("help")) {
340: showError(usage);
341: System.exit(1);
342: }
343:
344: MetricsFactory factory;
345:
346: if (commandLine.isPresent("configuration")) {
347: factory = new MetricsFactory("Project",
348: new MetricsConfigurationLoader(commandLine
349: .getToggleSwitch("validate"))
350: .load(commandLine
351: .getSingleSwitch("configuration")));
352: } else {
353: factory = new MetricsFactory(
354: "Project",
355: new MetricsConfigurationLoader(commandLine
356: .getToggleSwitch("validate"))
357: .load(commandLine
358: .getSingleSwitch("default-configuration")));
359: }
360:
361: /*
362: * Beginning of main processing
363: */
364:
365: try {
366: UIManager.setLookAndFeel(UIManager
367: .getSystemLookAndFeelClassName());
368: } catch (Exception ex) {
369: // Ignore
370: }
371:
372: OOMetrics model = new OOMetrics(factory);
373: model.setVisible(true);
374: }
375: }
|