KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > jclasslib > mdi > BasicDesktopManager


1 /*
2     This library is free software; you can redistribute it and/or
3     modify it under the terms of the GNU General Public
4     License as published by the Free Software Foundation; either
5     version 2 of the license, or (at your option) any later version.
6 */

7
8 package org.gjt.jclasslib.mdi;
9
10 import javax.swing.*;
11 import javax.swing.event.InternalFrameEvent JavaDoc;
12 import javax.swing.event.InternalFrameListener JavaDoc;
13 import java.awt.*;
14 import java.awt.event.*;
15 import java.beans.*;
16 import java.util.*;
17
18 /**
19     <tt>DesktopManager</tt> for MDI application.
20
21     @author <a HREF="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>
22     @version $Revision: 1.7 $ $Date: 2003/08/18 07:59:50 $
23 */

24 public class BasicDesktopManager extends DefaultDesktopManager
25                                  implements VetoableChangeListener,
26                                             InternalFrameListener JavaDoc
27  {
28     private static int NEW_INTERNAL_X_OFFSET = 22;
29     private static int NEW_INTERNAL_Y_OFFSET = 22;
30     private static int NEW_INTERNAL_WIDTH = 600;
31     private static int NEW_INTERNAL_HEIGHT = 400;
32
33     /** Parent frame of this <tt>DesktopManager</tt>. */
34     protected BasicMDIFrame parentFrame;
35
36     private int newInternalX = 0;
37     private int newInternalY = 0;
38
39     private JDesktopPane desktopPane;
40     private HashMap frameToMenuItem = new HashMap();
41     private BasicInternalFrame activeFrame;
42     private LinkedList openFrames = new LinkedList();
43     private int rollover = 0;
44     private int separatorMenuIndex = -1;
45
46     private boolean maximizationInProgress;
47     private boolean anyFrameMaximized;
48
49     /**
50      * Constructor.
51      * @param parentFrame the parent frame.
52      */

53     public BasicDesktopManager(BasicMDIFrame parentFrame) {
54         this.parentFrame = parentFrame;
55         desktopPane = parentFrame.desktopPane;
56     }
57
58     /**
59         Get the parent frame.
60         @return the frame
61      */

62     public BasicMDIFrame getParentFrame() {
63         return parentFrame;
64     }
65
66     /**
67         Get the associated <tt>JDesktopPane</tt>.
68         @return the <tt>JDesktopPane</tt>
69      */

70     public JDesktopPane getDesktopPane() {
71         return desktopPane;
72     }
73
74     /**
75         Get the list of open child frames.
76         @return the list
77      */

78     public java.util.List JavaDoc getOpenFrames() {
79         return openFrames;
80     }
81
82     /**
83         Get a rectangle for a new child frame.
84         @return the rectangle
85      */

86     public Rectangle getNextInternalFrameBounds() {
87
88         if (newInternalY + NEW_INTERNAL_HEIGHT > desktopPane.getHeight()) {
89             rollover++;
90             newInternalY = 0;
91             newInternalX = rollover * NEW_INTERNAL_X_OFFSET;
92         }
93
94         Rectangle nextBounds = new Rectangle(newInternalX,
95                              newInternalY,
96                              NEW_INTERNAL_WIDTH,
97                              NEW_INTERNAL_HEIGHT);
98
99         newInternalX += NEW_INTERNAL_X_OFFSET;
100         newInternalY += NEW_INTERNAL_Y_OFFSET;
101
102         return nextBounds;
103     }
104
105     /**
106         Set the index of the frame to be shown on top after a call to <tt>showAll()</tt>.
107         @param activeFrame the index
108      */

109     public void setActiveFrame(BasicInternalFrame activeFrame) {
110         this.activeFrame = activeFrame;
111     }
112
113     /**
114         Look for an open frame with an equivalent init parameter.
115         @param initParam the init parameter to look for.
116         @return the open frame or <tt>null</tt>.
117      */

118     public BasicInternalFrame getOpenFrame(Object JavaDoc initParam) {
119
120         Iterator it = openFrames.iterator();
121         while (it.hasNext()) {
122             BasicInternalFrame frame = (BasicInternalFrame)it.next();
123             if (frame.getInitParam().equals(initParam)) {
124                 return frame;
125             }
126         }
127         return null;
128     }
129
130     /**
131         Show all internal frames.
132      */

133     public void showAll() {
134         Iterator it = openFrames.iterator();
135         while (it.hasNext()) {
136             ((BasicInternalFrame)it.next()).setVisible(true);
137         }
138         if (activeFrame != null) {
139             try {
140                 activeFrame.setSelected(true);
141             } catch (PropertyVetoException ex) {
142             }
143         }
144         checkSize();
145     }
146
147     /**
148         Add a child frame to this <tt>DesktopManager</tt>.
149         @param frame the frame
150      */

151     public void addInternalFrame(JInternalFrame frame) {
152
153         frame.addComponentListener(new ComponentAdapter() {
154             public void componentResized(ComponentEvent event) {
155                  checkSize();
156             }
157
158         });
159
160         if (frameToMenuItem.size() == 0) {
161             separatorMenuIndex = parentFrame.menuWindow.getMenuComponentCount();
162             parentFrame.menuWindow.addSeparator();
163         }
164         Action action = new WindowActivateAction(frame);
165         JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(action);
166         menuItem.setSelected(false);
167         parentFrame.menuWindow.add(menuItem);
168
169         desktopPane.add(frame);
170         frameToMenuItem.put(frame, menuItem);
171         openFrames.add(frame);
172         setWindowActionsEnabled(true);
173         checkSize();
174     }
175
176     /**
177         Cycle to the next child window.
178      */

179     public void cycleToNextWindow() {
180         cycleWindows(true);
181     }
182
183     /**
184         Cycle to the previous child window.
185      */

186     public void cycleToPreviousWindow() {
187         cycleWindows(false);
188     }
189
190     /**
191         Tile all child windows.
192      */

193     public void tileWindows() {
194
195         int framesCount = openFrames.size();
196         if (framesCount == 0) {
197             return;
198         }
199
200         resetSize();
201
202         int sqrt = (int)Math.sqrt(framesCount);
203         int rows = sqrt;
204         int cols = sqrt;
205         if (rows * cols < framesCount) {
206             cols++;
207             if (rows * cols < framesCount) {
208                 rows++;
209             }
210         }
211
212         Dimension size = desktopPane.getSize();
213
214         int width = size.width/cols;
215         int height = size.height/rows;
216         int offsetX = 0;
217         int offsetY = 0;
218
219         JInternalFrame currentFrame;
220         Iterator it = openFrames.iterator();
221         for (int i = 0; i < rows; i++) {
222             for (int j = 0; j < cols && (i * cols + j < framesCount); j++) {
223                 currentFrame = (JInternalFrame)it.next();
224                 normalizeFrame(currentFrame);
225                 resizeFrame(currentFrame, offsetX, offsetY, width, height);
226                 offsetX += width;
227             }
228             offsetX = 0;
229             offsetY += height;
230         }
231     }
232
233
234     /**
235         Stack all child windows.
236      */

237     public void stackWindows() {
238
239         newInternalX = newInternalY = rollover = 0;
240
241         Rectangle currentBounds;
242         JInternalFrame currentFrame;
243         Iterator it = openFrames.iterator();
244         while (it.hasNext()) {
245             currentFrame = (JInternalFrame)it.next();
246             normalizeFrame(currentFrame);
247             currentBounds = getNextInternalFrameBounds();
248             resizeFrame(currentFrame,
249                         currentBounds.x,
250                         currentBounds.y,
251                         currentBounds.width,
252                         currentBounds.height);
253             try {
254                 currentFrame.setSelected(true);
255             } catch (PropertyVetoException ex) {
256             }
257         }
258         checkSize();
259     }
260
261     public void vetoableChange(PropertyChangeEvent changeEvent)
262         throws PropertyVetoException {
263
264         String JavaDoc eventName = changeEvent.getPropertyName();
265
266         if (JInternalFrame.IS_MAXIMUM_PROPERTY.equals(eventName)) {
267             if (maximizationInProgress) {
268                 return;
269             }
270
271             boolean isMaximum = ((Boolean JavaDoc)changeEvent.getNewValue()).booleanValue();
272             if (isMaximum) {
273                 resetSize();
274             }
275             anyFrameMaximized = isMaximum;
276             JInternalFrame source = (JInternalFrame)changeEvent.getSource();
277             maximizeAllFrames(source, isMaximum);
278         }
279     }
280
281     public void activateFrame(JInternalFrame frame) {
282         super.activateFrame(frame);
283         Iterator it = frameToMenuItem.values().iterator();
284         while (it.hasNext()) {
285             JCheckBoxMenuItem menuItem = (JCheckBoxMenuItem)it.next();
286             menuItem.setSelected(false);
287
288         }
289         ((JCheckBoxMenuItem)frameToMenuItem.get(frame)).setSelected(true);
290     }
291
292     public void internalFrameDeiconified(InternalFrameEvent JavaDoc event) {
293     }
294
295     public void internalFrameOpened(InternalFrameEvent JavaDoc event) {
296     }
297
298     public void internalFrameIconified(InternalFrameEvent JavaDoc event) {
299     }
300
301     public void internalFrameClosing(InternalFrameEvent JavaDoc event) {
302         JInternalFrame frame = event.getInternalFrame();
303         removeInternalFrame(frame);
304     }
305
306     public void internalFrameActivated(InternalFrameEvent JavaDoc event) {
307     }
308
309     public void internalFrameDeactivated(InternalFrameEvent JavaDoc event) {
310     }
311
312     public void internalFrameClosed(InternalFrameEvent JavaDoc event) {
313         parentFrame.desktopPane.remove(event.getInternalFrame());
314         checkSize();
315     }
316
317     public void endResizingFrame(JComponent f) {
318         super.endResizingFrame(f);
319         checkSize();
320     }
321
322     public void endDraggingFrame(JComponent f) {
323         super.endDraggingFrame(f);
324         checkSize();
325     }
326
327     /**
328         Check if the desktop pane should be resized.
329      */

330     public void checkSize() {
331
332         Dimension size = new Dimension();
333         JInternalFrame[] frames = desktopPane.getAllFrames();
334         for (int i = 0; i < frames.length; i++) {
335             JInternalFrame frame = frames[i];
336             size.width = Math.max(size.width, frame.getX() + frame.getWidth());
337             size.height = Math.max(size.height, frame.getY() + frame.getHeight());
338         }
339         if (size.width > 0 && size.height > 0) {
340             desktopPane.setPreferredSize(size);
341         } else {
342             desktopPane.setPreferredSize(null);
343         }
344         desktopPane.revalidate();
345     }
346
347     /**
348         Check whether the desktop pane must be resized if in the maximized state.
349      */

350     public void checkResizeInMaximizedState() {
351         if (anyFrameMaximized) {
352             resetSize();
353         }
354     }
355
356     /**
357         Scroll the destop pane such that the given frame becoes fully visible.
358         @param frame the frame.
359      */

360     public void scrollToVisible(JInternalFrame frame) {
361         desktopPane.scrollRectToVisible(frame.getBounds());
362     }
363
364     private void removeInternalFrame(JInternalFrame frame) {
365
366         JMenuItem menuItem = (JMenuItem)frameToMenuItem.remove(frame);
367         if (menuItem != null) {
368             parentFrame.menuWindow.remove(menuItem);
369             openFrames.remove(frame);
370             if (frameToMenuItem.size() == 0 && separatorMenuIndex > -1) {
371                 parentFrame.menuWindow.remove(separatorMenuIndex);
372                 separatorMenuIndex = -1;
373                 setWindowActionsEnabled(false);
374             }
375         }
376     }
377
378     private void resetSize() {
379
380         desktopPane.setPreferredSize(null);
381         desktopPane.invalidate();
382         desktopPane.getParent().validate();
383         parentFrame.scpDesktop.invalidate();
384         parentFrame.scpDesktop.validate();
385     }
386
387     private void normalizeFrame(JInternalFrame frame) {
388
389         try {
390             if (frame.isIcon()) {
391                 frame.setIcon(false);
392             }
393             if (frame.isMaximum()) {
394                 frame.setMaximum(false);
395             }
396         } catch (PropertyVetoException ex) {
397         }
398     }
399
400     private void cycleWindows(boolean forward) {
401
402         JInternalFrame currentFrame = desktopPane.getSelectedFrame();
403         JInternalFrame nextFrame;
404
405         ListIterator it = openFrames.listIterator();
406         while (it.hasNext() && it.next() != currentFrame) {
407         }
408         if (forward) {
409             if (it.hasNext()) {
410                 nextFrame = (JInternalFrame)it.next();
411             } else {
412                 nextFrame = (JInternalFrame)openFrames.getFirst();
413             }
414         } else {
415             if (it.hasPrevious() && it.previous() != null && it.hasPrevious()) {
416                 nextFrame = (JInternalFrame)it.previous();
417             } else {
418                 nextFrame = (JInternalFrame)openFrames.getLast();
419             }
420         }
421
422         try {
423             if (nextFrame.isIcon()) {
424                 nextFrame.setIcon(false);
425             }
426             nextFrame.setSelected(true);
427             scrollToVisible(nextFrame);
428         } catch (PropertyVetoException ex) {
429         }
430     }
431
432     private void setWindowActionsEnabled(boolean enabled) {
433
434         parentFrame.actionNextWindow.setEnabled(enabled);
435         parentFrame.actionPreviousWindow.setEnabled(enabled);
436         parentFrame.actionTileWindows.setEnabled(enabled);
437         parentFrame.actionStackWindows.setEnabled(enabled);
438     }
439
440     private void maximizeAllFrames(JInternalFrame source, boolean isMaximum) {
441
442         synchronized (this) {
443             if (maximizationInProgress) {
444                 return;
445             }
446             maximizationInProgress = true;
447         }
448
449         try {
450             JInternalFrame[] frames = desktopPane.getAllFrames();
451             for (int i = 0; i < frames.length; i++) {
452                 if (frames[i] == source) {
453                     continue;
454                 }
455                 try {
456                     frames[i].setMaximum(isMaximum);
457                 } catch (PropertyVetoException ex) {
458                 }
459             }
460         } finally {
461             maximizationInProgress = false;
462         }
463     }
464
465     private class WindowActivateAction extends AbstractAction {
466
467         private JInternalFrame frame;
468
469         private WindowActivateAction(JInternalFrame frame) {
470             super(frame.getTitle());
471             this.frame = frame;
472         }
473
474         public void actionPerformed(ActionEvent event) {
475             try {
476                 if (frame.isIcon()) {
477                     frame.setIcon(false);
478                 }
479                 if (frame.isSelected()) {
480                     ((JCheckBoxMenuItem)event.getSource()).setSelected(true);
481                 } else {
482                     frame.setSelected(true);
483                 }
484                 scrollToVisible(frame);
485             } catch (PropertyVetoException ex) {
486             }
487         }
488
489     }
490 }
491
Popular Tags