001: /* Copyright (c) 2004 Christopher M Butler
002:
003: Permission is hereby granted, free of charge, to any person obtaining a copy of
004: this software and associated documentation files (the "Software"), to deal in the
005: Software without restriction, including without limitation the rights to use,
006: copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
007: Software, and to permit persons to whom the Software is furnished to do so, subject
008: to the following conditions:
009:
010: The above copyright notice and this permission notice shall be included in all
011: copies or substantial portions of the Software.
012:
013: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
014: INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
015: PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
016: HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
017: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
018: OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
019:
020: package org.gui4j.core.swing;
021:
022: import java.awt.Component;
023: import java.awt.Container;
024: import java.awt.Frame;
025: import java.awt.LayoutManager;
026: import java.awt.Point;
027: import java.awt.Rectangle;
028: import java.awt.Window;
029: import java.util.HashMap;
030: import java.util.HashSet;
031:
032: import javax.swing.JApplet;
033: import javax.swing.JComponent;
034: import javax.swing.JDialog;
035: import javax.swing.JFrame;
036: import javax.swing.JLayeredPane;
037: import javax.swing.JRootPane;
038: import javax.swing.JWindow;
039: import javax.swing.SwingUtilities;
040:
041: /**
042: * This class provides an abstraction of root containers used in Swing. It allows transparent use of
043: * methods common to <code>JFrame</code>, <code>JApplet</code>, <code>JWindow</code>, and
044: * <code>JDialog</code> without making an outward distinction between the different container types. This
045: * is accomplished by wrapping the root component.
046: *
047: * @author Chris Butler
048: */
049: public class RootWindow {
050: public static final Integer DEFAULT_MAXED_LAYER = new Integer(
051: JLayeredPane.PALETTE_LAYER.intValue() - 10);
052: private static final HashMap MAP_BY_ROOT_CONTAINER = new HashMap();
053: private LayoutManager maxedLayout;
054: private Integer maximizationLayer;
055: private Component root;
056:
057: private static Component getRoot(Component c) {
058: if (c == null)
059: return null;
060:
061: if (isValidRootContainer(c))
062: return c;
063:
064: Container parent = c.getParent();
065: while (parent != null && !isValidRootContainer(parent))
066: parent = parent.getParent();
067:
068: return parent;
069: }
070:
071: /**
072: * Traverses the container hierarchy to locate the root container and returns corresponding
073: * <code>RootSwingContainer</code>. If <code>c</code> is <code>null</code>, a <code>null</code>
074: * reference is returned.
075: * @param c the container whose root we wish to find
076: * @return the enclosing <code>RootSwingcontainer</code>
077: */
078: public static RootWindow getRootContainer(Component c) {
079: Component root = getRoot(c);
080: if (!isValidRootContainer(root))
081: return null;
082:
083: RootWindow container = (RootWindow) MAP_BY_ROOT_CONTAINER
084: .get(root);
085: if (container == null) {
086: container = new RootWindow(root);
087: MAP_BY_ROOT_CONTAINER.put(root, container);
088: }
089:
090: if (container.getRootContainer() != root)
091: container.setRootContainer(root);
092:
093: return container;
094: }
095:
096: /**
097: * Indicates whether the supplied <code>Component</code> is, in fact, a root Swing container.
098: *
099: * @param c the <code>Component</code> we wish to check
100: */
101: public static boolean isValidRootContainer(Component c) {
102: return c != null
103: && (c instanceof JFrame || c instanceof JApplet
104: || c instanceof JWindow || c instanceof JDialog);
105: }
106:
107: public static RootWindow[] getVisibleWindows() {
108: Frame[] frames = Frame.getFrames();
109: HashSet cache = new HashSet(frames.length);
110: for (int i = 0; i < frames.length; i++)
111: populateWindowList(new RootWindow(frames[i]), cache, true);
112: return (RootWindow[]) cache.toArray(new RootWindow[0]);
113: }
114:
115: private static void populateWindowList(RootWindow win,
116: HashSet winCache, boolean visOnly) {
117: if (win == null || winCache.contains(win))
118: return;
119:
120: if (visOnly && !win.getRootContainer().isVisible())
121: return;
122:
123: winCache.add(win);
124: Window[] children = win.getOwnedWindows();
125: for (int i = 0; i < children.length; i++)
126: populateWindowList(new RootWindow(children[i]), winCache,
127: visOnly);
128: }
129:
130: /**
131: * Creates a new <code>RootSwingContainer</code> wrapping the specified component.
132: */
133: protected RootWindow(Component root) {
134: setMaximizationLayer(DEFAULT_MAXED_LAYER);
135: setRootContainer(root);
136: }
137:
138: /**
139: * Returns the <code>contentPane</code> object for the wrapped component.
140: * @return the <code>contentPane</code> property
141: */
142: public Container getContentPane() {
143: if (root instanceof JFrame)
144: return ((JFrame) root).getContentPane();
145: if (root instanceof JApplet)
146: return ((JApplet) root).getContentPane();
147: if (root instanceof JWindow)
148: return ((JWindow) root).getContentPane();
149: if (root instanceof JDialog)
150: return ((JDialog) root).getContentPane();
151: return null;
152: }
153:
154: /**
155: * Returns the <code>glassPane</code> object for the wrapped component.
156: * @return the <code>glassPane</code> property
157: */
158: public Component getGlassPane() {
159: if (root instanceof JFrame)
160: return ((JFrame) root).getGlassPane();
161: if (root instanceof JApplet)
162: return ((JApplet) root).getGlassPane();
163: if (root instanceof JWindow)
164: return ((JWindow) root).getGlassPane();
165: if (root instanceof JDialog)
166: return ((JDialog) root).getGlassPane();
167: return null;
168: }
169:
170: /**
171: * Returns the <code>layeredPane</code> object for the wrapped component.
172: * @return the <code>layeredPane</code> property
173: */
174: public JLayeredPane getLayeredPane() {
175: if (root instanceof JFrame)
176: return ((JFrame) root).getLayeredPane();
177: if (root instanceof JApplet)
178: return ((JApplet) root).getLayeredPane();
179: if (root instanceof JWindow)
180: return ((JWindow) root).getLayeredPane();
181: if (root instanceof JDialog)
182: return ((JDialog) root).getLayeredPane();
183: return null;
184: }
185:
186: /**
187: * Gets the location of the wrapped component in the form of a point
188: * specifying the component's top-left corner in the screen's
189: * coordinate space.
190: * @return An instance of <code>Point</code> representing
191: * the top-left corner of the component's bounds in the
192: * coordinate space of the screen.
193: */
194: public Point getLocationOnScreen() {
195: if (root instanceof JFrame)
196: return ((JFrame) root).getLocationOnScreen();
197: else if (root instanceof JApplet)
198: return ((JApplet) root).getLocationOnScreen();
199: else if (root instanceof JWindow)
200: return ((JWindow) root).getLocationOnScreen();
201: else if (root instanceof JDialog)
202: return ((JDialog) root).getLocationOnScreen();
203: return null;
204: }
205:
206: /**
207: * Returns the layer associated with <code>Component</code> maximization within the
208: * <code>RootSwingContainer</code>.
209: *
210: * @return an <code>Integer</code> indicating the maximization layer property
211: */
212: public Integer getMaximizationLayer() {
213: return maximizationLayer;
214: }
215:
216: /**
217: * Returns the <code>LayoutManager</code> associated with <code>Component</code> maximization within the
218: * <code>RootSwingContainer</code>.
219: *
220: * @return a <code>LayoutManager</code> indicating the maximization layout property
221: */
222: public LayoutManager getMaximizedLayout() {
223: return maxedLayout;
224: }
225:
226: /**
227: * Returns the the wrapped component. (<code>JFrame</code>, <code>JApplet</code>, etc...)
228: * @return the wrapped root container
229: */
230: public Component getRootContainer() {
231: return root;
232: }
233:
234: /**
235: * Returns the <code>rootPane</code> object for the wrapped component.
236: * @return the <code>rootPane</code> property
237: */
238: public JRootPane getRootPane() {
239: if (root instanceof JFrame)
240: return ((JFrame) root).getRootPane();
241: else if (root instanceof JApplet)
242: return ((JApplet) root).getRootPane();
243: else if (root instanceof JWindow)
244: return ((JWindow) root).getRootPane();
245: else if (root instanceof JDialog)
246: return ((JDialog) root).getRootPane();
247: return null;
248: }
249:
250: /**
251: * Convenience method that calls <code>revalidate()</code> on the current content pane
252: * if it is a <code>JComponent</code>. If not, no action is taken.
253: */
254: public void revalidateContentPane() {
255: Container c = getContentPane();
256: if (c instanceof JComponent)
257: ((JComponent) c).revalidate();
258: }
259:
260: /**
261: * Sets the <code>contentPane</code> property for the wrapped component.
262: *
263: * @param contentPane the <code>contentPane</code> object for the wrapped component
264: */
265: public void setContentPane(Container contentPane) {
266: if (root instanceof JFrame)
267: ((JFrame) root).setContentPane(contentPane);
268: else if (root instanceof JApplet)
269: ((JApplet) root).setContentPane(contentPane);
270: else if (root instanceof JWindow)
271: ((JWindow) root).setContentPane(contentPane);
272: else if (root instanceof JDialog)
273: ((JDialog) root).setContentPane(contentPane);
274: }
275:
276: /**
277: * Sets the <code>glassPane</code> property for the wrapped component.
278: *
279: * @param glassPane the <code>glassPane</code> object for the wrapped component
280: */
281: public void setGlassPane(Component glassPane) {
282: if (root instanceof JFrame)
283: ((JFrame) root).setGlassPane(glassPane);
284: else if (root instanceof JApplet)
285: ((JApplet) root).setGlassPane(glassPane);
286: else if (root instanceof JWindow)
287: ((JWindow) root).setGlassPane(glassPane);
288: else if (root instanceof JDialog)
289: ((JDialog) root).setGlassPane(glassPane);
290: }
291:
292: /**
293: * Sets the <code>layeredPane</code> property for the wrapped component.
294: *
295: * @param layeredPane the <code>layeredPane</code> object for the wrapped component
296: */
297: public void setLayeredPane(JLayeredPane layeredPane) {
298: if (root instanceof JFrame)
299: ((JFrame) root).setLayeredPane(layeredPane);
300: else if (root instanceof JApplet)
301: ((JApplet) root).setLayeredPane(layeredPane);
302: else if (root instanceof JWindow)
303: ((JWindow) root).setLayeredPane(layeredPane);
304: else if (root instanceof JDialog)
305: ((JDialog) root).setLayeredPane(layeredPane);
306: }
307:
308: public Window[] getOwnedWindows() {
309: if (root instanceof JFrame)
310: return ((JFrame) root).getOwnedWindows();
311: else if (root instanceof JWindow)
312: return ((JWindow) root).getOwnedWindows();
313: else if (root instanceof JDialog)
314: return ((JDialog) root).getOwnedWindows();
315: else
316: return new Window[0];
317:
318: }
319:
320: /**
321: * Sets the layer associated with <code>Component</code> maximization within the
322: * <code>RootSwingContainer</code>. If <code>layer</code> is <code>null</code>,
323: * DEFAULT_MAXED_LAYER is used instead.
324: *
325: * @param layer an <code>Integer</code> indicating the maximization layer property
326: */
327: public void setMaximizationLayer(Integer layer) {
328: if (layer == null)
329: layer = DEFAULT_MAXED_LAYER;
330: maximizationLayer = layer;
331: }
332:
333: /**
334: * Sets the <code>LayoutManager</code> associated with <code>Component</code> maximization within the
335: * <code>RootSwingContainer</code>.
336: *
337: * @param mgr the <code>LayoutManager</code> associated with <code>Component</code> maximization
338: * within the <code>RootSwingContainer</code>.
339: */
340: public void setMaximizedLayout(LayoutManager mgr) {
341: maxedLayout = mgr;
342: }
343:
344: /**
345: * Sets the wrapped root container.
346: *
347: * @param root the new wrapped root container
348: */
349: protected void setRootContainer(Component root) {
350: this .root = root;
351: }
352:
353: public void updateComponentTreeUI() {
354: SwingUtilities.updateComponentTreeUI(root);
355: pack();
356: }
357:
358: public void pack() {
359: if (root instanceof JFrame)
360: ((JFrame) root).pack();
361: else if (root instanceof JWindow)
362: ((JWindow) root).pack();
363: else if (root instanceof JDialog)
364: ((JDialog) root).pack();
365: }
366:
367: public void toFront() {
368: if (root instanceof JFrame)
369: ((JFrame) root).toFront();
370: else if (root instanceof JWindow)
371: ((JWindow) root).toFront();
372: else if (root instanceof JDialog)
373: ((JDialog) root).toFront();
374: }
375:
376: public boolean isActive() {
377: if (root instanceof JFrame)
378: return ((JFrame) root).isActive();
379: else if (root instanceof JWindow)
380: return ((JWindow) root).isActive();
381: else if (root instanceof JDialog)
382: return ((JDialog) root).isActive();
383: return false;
384: }
385:
386: public Window getOwner() {
387: if (root instanceof JFrame)
388: return ((JFrame) root).getOwner();
389: else if (root instanceof JWindow)
390: return ((JWindow) root).getOwner();
391: else if (root instanceof JDialog)
392: return ((JDialog) root).getOwner();
393: return null;
394: }
395:
396: public Rectangle getBounds() {
397: if (root instanceof JFrame)
398: return ((JFrame) root).getBounds();
399: if (root instanceof JApplet)
400: return ((JApplet) root).getBounds();
401: else if (root instanceof JWindow)
402: return ((JWindow) root).getBounds();
403: else if (root instanceof JDialog)
404: return ((JDialog) root).getBounds();
405: return null;
406: }
407: }
|