001: /*
002: * $Id: JGraphpadWindowMenu.java,v 1.2 2005/10/15 16:35:35 gaudenz Exp $
003: * Copyright (c) 2001-2005, Gaudenz Alder
004: *
005: * All rights reserved.
006: *
007: * See LICENSE file for license details. If you are unable to locate
008: * this file please contact info (at) jgraph (dot) com.
009: */
010: package com.jgraph.pad.factory;
011:
012: import java.awt.Component;
013: import java.awt.event.ActionEvent;
014: import java.awt.event.ContainerEvent;
015: import java.awt.event.ContainerListener;
016: import java.beans.PropertyChangeEvent;
017: import java.beans.PropertyChangeListener;
018: import java.beans.PropertyVetoException;
019: import java.util.ArrayList;
020: import java.util.Iterator;
021: import java.util.List;
022:
023: import javax.swing.AbstractAction;
024: import javax.swing.ButtonGroup;
025: import javax.swing.JDesktopPane;
026: import javax.swing.JInternalFrame;
027: import javax.swing.JMenu;
028: import javax.swing.JMenuItem;
029: import javax.swing.JRadioButtonMenuItem;
030:
031: import org.w3c.dom.Node;
032:
033: import com.jgraph.JGraphEditor;
034: import com.jgraph.editor.JGraphEditorResources;
035: import com.jgraph.editor.factory.JGraphEditorFactoryMethod;
036:
037: /**
038: * Window menu to activate internal frames in an editor pane.
039: */
040: public class JGraphpadWindowMenu extends JMenu implements
041: ContainerListener {
042:
043: /**
044: * Specifies the resource key for the menu label. Default is
045: * <code>windowMenu.label</code>.
046: */
047: public static String KEY_MENULABEL = "windowMenu.label";
048:
049: /**
050: * Specifies the key under which to store the window menu for later
051: * reference.
052: */
053: public static String KEY_WINDOWMENU = "windowMenu";
054:
055: /**
056: * References the desktop pane that this menu represents. This is assigned
057: * only after the desktop pane has been created by the respective factory
058: * method.
059: */
060: protected JDesktopPane desktopPane;
061:
062: /**
063: * Holds all dynamically created items.
064: */
065: protected List items = new ArrayList();
066:
067: /**
068: * Constructs a new window menu using {@link #KEY_MENULABEL}.
069: */
070: public JGraphpadWindowMenu() {
071: super (JGraphEditorResources.getString(KEY_MENULABEL));
072:
073: // Adds cascade all action
074: add(new JMenuItem(new AbstractAction(JGraphEditorResources
075: .getString("cascadeAll.label")) {
076:
077: /*
078: * (non-Javadoc)
079: */
080: public void actionPerformed(ActionEvent e) {
081: doCascadeAll();
082: }
083: }));
084:
085: // Adds maximize all action
086: add(new JMenuItem(new AbstractAction(JGraphEditorResources
087: .getString("maximizeAll.label")) {
088:
089: /*
090: * (non-Javadoc)
091: */
092: public void actionPerformed(ActionEvent e) {
093: doMaximizeAll();
094: }
095: }));
096:
097: // Adds minimize all action
098: add(new JMenuItem(new AbstractAction(JGraphEditorResources
099: .getString("minimizeAll.label")) {
100:
101: /*
102: * (non-Javadoc)
103: */
104: public void actionPerformed(ActionEvent e) {
105: doMinimizeAll();
106: }
107: }));
108:
109: addSeparator();
110: }
111:
112: /**
113: * Returns the desktop pane.
114: *
115: * @return Returns the desktopPane.
116: */
117: public JDesktopPane getDesktopPane() {
118: return desktopPane;
119: }
120:
121: /**
122: * Sets the desktop pane and adds this as a container listener.
123: *
124: * @param desktopPane
125: * The desktopPane to set.
126: */
127: public void setDesktopPane(JDesktopPane desktopPane) {
128: this .desktopPane = desktopPane;
129: desktopPane.addContainerListener(this );
130: }
131:
132: /**
133: * Maximizes all internal frames in {@link #desktopPane}.
134: */
135: public void doMaximizeAll() {
136: if (desktopPane != null) {
137: try {
138: JInternalFrame selectedFrame = null;
139: JInternalFrame[] frames = desktopPane.getAllFrames();
140: for (int i = 0; i < frames.length; i++) {
141: if (frames[i].isSelected())
142: selectedFrame = frames[i];
143: frames[i].setIcon(false);
144: frames[i].setMaximum(true);
145: }
146: if (selectedFrame != null) {
147: selectedFrame.toFront();
148: selectedFrame.setSelected(true);
149: }
150: } catch (java.beans.PropertyVetoException pvex) {
151: // empty
152: }
153: }
154: }
155:
156: /**
157: * Minimizes all internal frames in {@link #desktopPane}.
158: */
159: protected void doMinimizeAll() {
160: if (desktopPane != null) {
161: try {
162: JInternalFrame[] frames = desktopPane.getAllFrames();
163: for (int i = 0; i < frames.length; i++) {
164: frames[i].setIcon(true);
165: frames[i].setMaximum(false);
166: }
167: } catch (java.beans.PropertyVetoException pvex) {
168: // empty
169: }
170: }
171: }
172:
173: /**
174: * Cascades all internal frames in {@link #desktopPane}.
175: */
176: protected void doCascadeAll() {
177: if (desktopPane != null) {
178: JInternalFrame[] frames = desktopPane.getAllFrames();
179:
180: int desktopX = frames[0].getX();
181: int desktopY = frames[0].getY();
182: int desktopWidth = frames[0].getWidth();
183: int desktopHeight = frames[0].getHeight();
184: int diffWidth = 20;
185: int diffHeight = 20;
186:
187: for (int i = 0; i < frames.length; i++) {
188: int frmWidth = desktopWidth - (frames.length - 1)
189: * diffWidth;
190: int frmHeight = desktopHeight - (frames.length - 1)
191: * diffHeight;
192:
193: try {
194: frames[i].setIcon(false);
195: frames[i].setMaximum(false);
196: } catch (java.beans.PropertyVetoException pvex) {
197: // empty
198: }
199:
200: frames[i].setLocation(desktopX, desktopY);
201: frames[i].setSize(frmWidth, frmHeight);
202:
203: desktopX += diffWidth;
204: desktopY += diffHeight;
205: }
206: desktopPane.getSelectedFrame().toFront();
207: }
208: }
209:
210: /**
211: * Reloads all dynamic items in the menu.
212: */
213: protected void updateItems() {
214: if (desktopPane != null) {
215: Iterator it = items.iterator();
216:
217: // Removes all existing dynamic items
218: while (it.hasNext())
219: remove((JMenuItem) it.next());
220: items.clear();
221:
222: // Adds a new item for each internal frame
223: ButtonGroup group = new ButtonGroup();
224: JInternalFrame[] frames = desktopPane.getAllFrames();
225: if (frames.length == 0) {
226: JMenuItem item = new JMenuItem(JGraphEditorResources
227: .getString("NoDocument"));
228: item.setEnabled(false);
229: items.add(item);
230: add(item);
231: } else {
232: for (int i = 0; i < frames.length; i++) {
233: JInternalFrame frame = frames[i];
234: JMenuItem item = createItem(frame);
235: items.add(item);
236: group.add(item);
237: add(item);
238: }
239: }
240: invalidate();
241: }
242: }
243:
244: /**
245: * Creates a new menuitem for the specified internal frame adding an action
246: * listener that brings the respective frame to front. The menu item is
247: * automatically updated if the frame's title changes or if the frame is
248: * selected.
249: *
250: * @param frame
251: * The internal frame that the item represents.
252: * @return Returns a new menu item for <code>frame</code>.
253: */
254: protected JMenuItem createItem(final JInternalFrame frame) {
255: final JRadioButtonMenuItem item = new JRadioButtonMenuItem(
256: new AbstractAction(frame.getTitle()) {
257:
258: /*
259: * (non-Javadoc)
260: */
261: public void actionPerformed(ActionEvent e) {
262: try {
263: frame.setIcon(false);
264: frame.setSelected(true);
265: } catch (PropertyVetoException e1) {
266: // ignore
267: }
268: frame.toFront();
269: }
270: });
271:
272: // Adds a property change listener to the frame to keep the
273: // menu item state up-to-date.
274: frame.addPropertyChangeListener(new PropertyChangeListener() {
275:
276: /*
277: * (non-Javadoc)
278: */
279: public void propertyChange(PropertyChangeEvent evt) {
280: item.setText(frame.getTitle());
281: item.setSelected(frame.isSelected());
282: invalidate();
283: }
284:
285: });
286: return item;
287: }
288:
289: /*
290: * (non-Javadoc)
291: */
292: public void componentAdded(ContainerEvent e) {
293: updateItems();
294: }
295:
296: /*
297: * (non-Javadoc)
298: */
299: public void componentRemoved(ContainerEvent e) {
300: updateItems();
301: }
302:
303: /**
304: * Provides a factory method to construct a window menu for an editor.
305: */
306: public static class FactoryMethod extends JGraphEditorFactoryMethod {
307:
308: /**
309: * Defines the default name for factory methods of this kind.
310: */
311: public static String NAME = "createWindowMenu";
312:
313: /**
314: * References the enclosing editor.
315: */
316: protected JGraphEditor editor;
317:
318: /**
319: * Constructs a new factory method for the specified enclosing editor
320: * using {@link #NAME}.
321: *
322: * @param editor
323: * The editor that contains the factory method.
324: */
325: public FactoryMethod(JGraphEditor editor) {
326: super (NAME);
327: this .editor = editor;
328: }
329:
330: /*
331: * (non-Javadoc)
332: */
333: public Component createInstance(Node configuration) {
334: JMenu menu = new JGraphpadWindowMenu();
335: editor.getSettings().putObject(KEY_WINDOWMENU, menu);
336: return menu;
337: }
338: }
339:
340: }
|