001: /*
002: * ====================================================================
003: * The JRefactory License, Version 1.0
004: *
005: * Copyright (c) 2003 JRefactory. All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution,
020: * if any, must include the following acknowledgment:
021: * "This product includes software developed by the
022: * JRefactory (http://www.sourceforge.org/projects/jrefactory)."
023: * Alternately, this acknowledgment may appear in the software itself,
024: * if and wherever such third-party acknowledgments normally appear.
025: *
026: * 4. The names "JRefactory" must not be used to endorse or promote
027: * products derived from this software without prior written
028: * permission. For written permission, please contact seguin@acm.org.
029: *
030: * 5. Products derived from this software may not be called "JRefactory",
031: * nor may "JRefactory" appear in their name, without prior written
032: * permission of Chris Seguin.
033: *
034: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
035: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
036: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
037: * DISCLAIMED. IN NO EVENT SHALL THE CHRIS SEGUIN OR
038: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
039: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
040: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
041: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
042: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
043: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
044: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
045: * SUCH DAMAGE.
046: * ====================================================================
047: *
048: * This software consists of voluntary contributions made by many
049: * individuals on behalf of JRefactory. For more information on
050: * JRefactory, please see
051: * <http://www.sourceforge.org/projects/jrefactory>.
052: */
053: package org.acm.seguin.ide.common;
054:
055: import java.awt.Point;
056: import java.awt.BorderLayout;
057: import java.awt.Dimension;
058: import java.awt.event.ActionEvent;
059: import java.awt.event.ActionListener;
060: import java.awt.event.MouseEvent;
061: import java.awt.event.MouseAdapter;
062: import java.awt.event.MouseListener;
063: import java.io.IOException;
064: import java.util.HashMap;
065: import java.util.Iterator;
066: import javax.swing.*;
067: import javax.swing.tree.*;
068: import javax.swing.border.EmptyBorder;
069: import org.acm.seguin.ide.common.PackageSelectorArea;
070: import org.acm.seguin.io.Saveable;
071: import org.acm.seguin.io.AllFileFilter;
072: import org.acm.seguin.summary.PackageSummary;
073: import org.acm.seguin.summary.SummaryTraversal;
074: import net.sourceforge.jrefactory.action.LoadPackageAction;
075: import net.sourceforge.jrefactory.uml.UMLPackage;
076: import net.sourceforge.jrefactory.uml.loader.Reloader;
077: import net.sourceforge.jrefactory.uml.loader.ReloaderSingleton;
078: import org.acm.seguin.ide.command.CommandLineMenu;
079: import org.acm.seguin.ide.command.ExitMenuSelection;
080: import org.acm.seguin.summary.load.SwingLoadStatus;
081:
082: /**
083: * Creates a panel for the selection of packages to view.
084: *
085: * @author Mike Atkinson
086: * @created June 26, 2003
087: */
088: public class PackageSelectorPanel extends PackageSelectorArea implements
089: ActionListener, Saveable, Reloader, Runnable {
090:
091: protected JPanel buttons;
092: protected JPanel panel;
093: protected JFrame frame;
094: protected SwingLoadStatus loadStatus;
095:
096: public static PackageSelectorPanel mainPanel;
097: /**
098: * The root directory
099: */
100: protected String rootDir = null;
101:
102: protected HashMap viewList;
103:
104: /**
105: * Constructor for the PackageSelectorPanel object
106: *
107: * @param root The root directory
108: */
109: protected PackageSelectorPanel(String root) {
110: super ();
111: setRootDirectory(root); // Setup the instance variables
112:
113: buttons = createButtons(this );
114: loadStatus = new SwingLoadStatus();
115: loadStatus.setVisible(false);
116: panel = createMainPanel();
117: MouseListener mouseListener = new MouseAdapter() {
118: public void mousePressed(MouseEvent mevt) {
119: maybeShowMenu(mevt);
120: }
121:
122: public void mouseReleased(MouseEvent mevt) {
123: maybeShowMenu(mevt);
124: }
125:
126: public void mouseClicked(MouseEvent e) {
127: if (e.getClickCount() == 2) {
128: //int index = packages.locationToIndex(e.getPoint());
129: Point pt = e.getPoint();
130: TreePath selection = packages.getPathForLocation(
131: pt.x, pt.y);
132: //System.out.println("Double clicked on Item " + index);
133: if (selection != null) {
134: ANode node = (ANode) selection
135: .getLastPathComponent();
136: Object userObject = node.getUserObject();
137: if (userObject instanceof NodeData) {
138: PackageSummary summary = ((NodeData) userObject)
139: .getPackageSummary();
140: if (summary != null) {
141: showSummary(summary);
142: }
143: } else {
144: System.out.println("userObject="
145: + userObject);
146: }
147: }
148: }
149: }
150: };
151: packages.addMouseListener(mouseListener);
152:
153: loadStatus.setLabel("waiting");
154: }
155:
156: private void maybeShowMenu(MouseEvent mevt) {
157: if (mevt.isPopupTrigger()) {
158: Point pt = mevt.getPoint();
159: TreePath selection = packages
160: .getPathForLocation(pt.x, pt.y);
161: if (selection != null) {
162: ANode node = (ANode) selection.getLastPathComponent();
163: JPopupMenu menu = new JPopupMenu("Module");
164: JMenuItem item = new JMenuItem(new RemoveAction(node));
165: item.setEnabled(node instanceof ModuleNode);
166: menu.add(item);
167: //menu.setLocation(pt.x, pt.y + 20);
168: //menu.setVisible(true);
169: menu
170: .show(mevt.getComponent(), mevt.getX(), mevt
171: .getY());
172: }
173: }
174: }
175:
176: private class RemoveAction extends AbstractAction {
177: ANode node;
178:
179: public RemoveAction(ANode node) {
180: super ("remove");
181: this .node = node;
182: }
183:
184: public void actionPerformed(ActionEvent evt) {
185: System.out.println("evt=" + evt);
186: model.removeNodeFromParent(node);
187: saveKnownModules();
188: }
189: }
190:
191: /**
192: * Set the root directory
193: *
194: *@param root the new root directory
195: */
196: public String getRootDirectory() {
197: return rootDir;
198: }
199:
200: /**
201: * Set the root directory
202: *
203: *@param root the new root directory
204: */
205: protected void setRootDirectory(String root) {
206: if (root == null) {
207: rootDir = System.getProperty("user.dir");
208: } else {
209: rootDir = root;
210: }
211: }
212:
213: /**
214: * Handle the button press events
215: *
216: * @param evt the event
217: */
218: public void actionPerformed(ActionEvent evt) {
219: String command = evt.getActionCommand();
220: if (command.equals("Show")) {
221: TreePath[] selection = packages.getSelectionPaths();
222: for (int ndx = 0; ndx < selection.length; ndx++) {
223: NodeData next = (NodeData) ((ANode) selection[ndx]
224: .getLastPathComponent()).getUserObject();
225: showSummary(next.getPackageSummary());
226: }
227: } else if (command.equals("Hide")) {
228: TreePath[] selection = packages.getSelectionPaths();
229: for (int ndx = 0; ndx < selection.length; ndx++) {
230: NodeData next = (NodeData) ((ANode) selection[ndx]
231: .getLastPathComponent()).getUserObject();
232: hideSummary(next.getPackageSummary());
233: }
234: } else if (command.equals("Reload")) {
235: ReloaderSingleton.reload();
236: } else if (command.equals("Load")) {
237: JFileChooser chooser = new JFileChooser();
238:
239: // Add other file filters - All
240: AllFileFilter allFilter = new AllFileFilter();
241: chooser.addChoosableFileFilter(allFilter);
242:
243: // Set it so that files and directories can be selected
244: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
245:
246: // Set the directory to the current directory
247: chooser.setCurrentDirectory(new java.io.File(rootDir));
248:
249: int returnVal = chooser.showOpenDialog(null);
250: if (returnVal == JFileChooser.APPROVE_OPTION) {
251: rootDir = chooser.getSelectedFile().getAbsolutePath();
252: ReloaderSingleton.register(this );
253: ReloaderSingleton.reload();
254: } else {
255: // do nothing
256: }
257: }
258: }
259:
260: /**
261: * Get the main panel.
262: *
263: *@return The main panel
264: */
265: public JPanel getPanel() {
266: return panel;
267: }
268:
269: /**
270: * Get the main panel (as a window), setting it visible.
271: *
272: *@param directory Description of Parameter
273: *@return The MainPanel value
274: */
275: public static PackageSelectorPanel openMainFrame(String directory) {
276: getMainFrame(directory);
277: if (mainPanel != null) {
278: mainPanel.setVisible(true);
279: }
280: return mainPanel;
281: }
282:
283: /**
284: * Get the package from the central store
285: *
286: * @param summary The package summary that we are looking for
287: * @return The UML package
288: */
289: protected UMLFrame getPackage(PackageSummary summary) {
290: return (UMLFrame) viewList.get(summary);
291: }
292:
293: /**
294: * Creates the frame
295: *
296: * @return Description of the Returned Value
297: */
298: protected JFrame createFrame() {
299: JFrame frame = new JFrame("Package Selector");
300:
301: frame.getContentPane().add(panel);
302:
303: CommandLineMenu clm = new CommandLineMenu();
304: frame.setJMenuBar(clm.getMenuBar(this ));
305: frame.addWindowListener(new ExitMenuSelection());
306: frame.setSize(350, 350);
307: return frame;
308: }
309:
310: /**
311: * Creates the content panel
312: *
313: * @return Description of the Returned Value
314: */
315: protected JPanel createMainPanel() {
316: JPanel panel = new JPanel();
317: panel.setLayout(new BorderLayout());
318:
319: JScrollPane scrollPane = getScrollPane();
320: //scrollPane.setBorder(new EmptyBorder(10, 10, 10, 10));
321: panel.add(scrollPane, BorderLayout.CENTER);
322: panel.add(buttons, BorderLayout.NORTH);
323: panel.add(loadStatus.getPanel(), BorderLayout.SOUTH);
324: return panel;
325: }
326:
327: /**
328: * Create the panel holding the buttons
329: *
330: * @param listener Description of Parameter
331: * @return Description of the Returned Value
332: */
333: protected JPanel createButtons(ActionListener listener) {
334: JPanel panel = new JPanel();
335:
336: panel.add(new JButton(new LoadPackageAction(null)));
337:
338: JButton showButton = new JButton("Show");
339: panel.add(showButton);
340: showButton.addActionListener(listener);
341:
342: JButton hideButton = new JButton("Hide");
343: panel.add(hideButton);
344: hideButton.addActionListener(listener);
345:
346: JButton reloadButton = new JButton("Reload");
347: panel.add(reloadButton);
348: reloadButton.addActionListener(listener);
349:
350: return panel;
351: }
352:
353: /**
354: * Creates a new view
355: *
356: *@param packageSummary The packages summary
357: */
358: private void createNewView(PackageSummary packageSummary) {
359: UMLFrame frame = new UMLFrame(packageSummary);
360: addPackage(packageSummary, frame);
361: }
362:
363: /**
364: * Add package to central store
365: *
366: *@param summary the summary we are adding
367: *@param view the associated view
368: */
369: protected void addPackage(PackageSummary summary, UMLFrame view) {
370: viewList.put(summary, view);
371: }
372:
373: /**
374: * Hide the summary
375: *
376: *@param packageSummary the summary to hide
377: */
378: private void hideSummary(PackageSummary packageSummary) {
379: UMLFrame view = getPackage(packageSummary);
380: view.setVisible(false);
381: }
382:
383: /**
384: * Loads the packages into the packages structure and refreshes the UML diagrams
385: */
386: public void loadPackages() {
387: new Thread(this ).start();
388: }
389:
390: public void run() {
391: try {
392: loadSummaries();
393: super .loadPackages();
394:
395: javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
396: public void run() {
397: // Reloads the screens
398: UMLPackage view = null;
399: PackageSummary packageSummary = null;
400:
401: if (viewList == null) {
402: viewList = new HashMap();
403: return;
404: }
405:
406: Iterator iter = viewList.keySet().iterator();
407: while (iter.hasNext()) {
408: packageSummary = (PackageSummary) iter.next();
409: view = getPackage(packageSummary)
410: .getUmlPackage();
411: view.reload();
412: }
413: }
414: });
415: } catch (Exception e) {
416: }
417: }
418:
419: /**
420: * Load the summaries
421: */
422: public void loadSummaries() {
423: // Load the summaries
424: SummaryLoaderThread loader = new SummaryLoaderThread(rootDir,
425: loadStatus);
426: try {
427: loader.start();
428: while (loader.waitForLoading() == 0) {
429: Thread.sleep(10);
430: }
431: } catch (InterruptedException e) {
432: }
433: }
434:
435: /**
436: * Main program for testing purposes
437: *
438: *@param args The command line arguments
439: */
440: public static void main(String[] args) {
441: if (args.length != 1) {
442: System.out
443: .println("Syntax: java net.sourceforge.jrefactory.uml.PackageSelectorPanel <dir>");
444: return;
445: }
446:
447: PackageSelectorPanel panel = PackageSelectorPanel
448: .openMainFrame(args[0]);
449: ReloaderSingleton.register(panel);
450: }
451:
452: /**
453: * Reloads the package information
454: */
455: public void reload() {
456: loadPackages();
457: }
458:
459: /**
460: * Saves the diagrams
461: *
462: *@exception IOException Description of Exception
463: */
464: public void save() throws IOException {
465: Iterator iter = viewList.keySet().iterator();
466: while (iter.hasNext()) {
467: PackageSummary packageSummary = (PackageSummary) iter
468: .next();
469: UMLPackage view = getPackage(packageSummary)
470: .getUmlPackage();
471: view.save();
472: }
473: }
474:
475: /**
476: * Shows the summary
477: *
478: *@param packageSummary the summary to show
479: */
480: private void showSummary(PackageSummary packageSummary) {
481: UMLFrame view = getPackage(packageSummary);
482: if ((view == null)
483: && (packageSummary.getFileSummaries() != null)) {
484: createNewView(packageSummary);
485: } else if (packageSummary.getFileSummaries() == null) {
486: // Nothing to view
487: } else {
488: view.getUmlPackage().reload();
489: view.setVisible(true);
490: }
491: }
492:
493: /**
494: * Get the main panel
495: *
496: * @param directory Description of Parameter
497: * @return The MainPanel value
498: */
499: public static PackageSelectorPanel getMainPanel(String directory) {
500: if (mainPanel == null) {
501: mainPanel = new PackageSelectorPanel(directory);
502: } else if (directory != null) {
503: mainPanel.setRootDirectory(directory);
504: }
505: return mainPanel;
506: }
507:
508: /**
509: * Get the main panel
510: *
511: * @param directory Description of Parameter
512: * @return The MainPanel value
513: */
514: public static JFrame getMainFrame(String directory) {
515: getMainPanel(directory);
516: if (mainPanel.frame == null) {
517: mainPanel.frame = mainPanel.createFrame();
518: }
519: return mainPanel.frame;
520: }
521: }
|