KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.gjt.jclasslib.util.GUIHelper;
11
12 import javax.swing.*;
13 import java.awt.*;
14 import java.awt.event.*;
15 import java.beans.PropertyVetoException JavaDoc;
16 import java.lang.reflect.Constructor JavaDoc;
17 import java.util.*;
18 import java.util.List JavaDoc;
19 import java.util.prefs.Preferences JavaDoc;
20
21
22 /**
23     Parent frame for MDI application. Handles window actions, state saving and loading
24     and supplies various utility methods.
25  
26     @author <a HREF="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>
27     @version $Revision: 1.8 $ $Date: 2004/06/29 15:41:44 $
28 */

29 public class BasicMDIFrame extends JFrame {
30
31     private static final int DEFAULT_WINDOW_WIDTH = 800;
32     private static final int DEFAULT_WINDOW_HEIGHT = 600;
33
34     private static final String JavaDoc SETTINGS_WINDOW_WIDTH = "windowWidth";
35     private static final String JavaDoc SETTINGS_WINDOW_HEIGHT = "windowHeight";
36     private static final String JavaDoc SETTINGS_WINDOW_X = "windowX";
37     private static final String JavaDoc SETTINGS_WINDOW_Y = "windowY";
38     private static final String JavaDoc SETTINGS_WINDOW_MAXIMIZED = "windowMaximized";
39
40     // Actions
41

42     /** Action for selecting the next child window. */
43     protected Action actionNextWindow;
44     /** Action for selecting the provious child window. */
45     protected Action actionPreviousWindow;
46     /** Action for tiling all child windows. */
47     protected Action actionTileWindows;
48     /** Action for stacking all child windows. */
49     protected Action actionStackWindows;
50
51     // Visual components
52

53     /** <tt>JDesktop</tt> pane which contains all child windows. */
54     protected JScrollPane scpDesktop;
55     /** The desktop pane. */
56     protected JDesktopPane desktopPane;
57     /** <tt>DesktopManager</tt> for this MDI parent frame. */
58     protected BasicDesktopManager desktopManager;
59     /** <tt>JMenu</tt> for window actions. */
60     protected JMenu menuWindow;
61
62     private Rectangle lastNormalFrameBounds;
63
64     /**
65         Constructor.
66      */

67     public BasicMDIFrame() {
68
69         setupActions();
70         setupMenu();
71         setupFrame();
72         setupEventHandlers();
73         loadWindowSettings();
74     }
75
76     /**
77         Create a <tt>BasicDesktopManager</tt> for this MDI parent window.
78         @return the <tt>BasicDesktopManager</tt>
79      */

80     protected BasicDesktopManager createDesktopManager() {
81         
82         return new BasicDesktopManager(this);
83     }
84     
85     /**
86         Exit the application.
87      */

88     protected void doQuit() {
89
90         saveWindowSettings();
91         dispose();
92         System.exit(0);
93     }
94
95     /**
96         Close all internal frames.
97      */

98     protected void closeAllFrames() {
99
100         List JavaDoc frames = desktopManager.getOpenFrames();
101         while (frames.size() > 0) {
102             BasicInternalFrame frame = (BasicInternalFrame)frames.get(0);
103             frame.doDefaultCloseAction();
104         }
105     }
106
107     /**
108          Create an <tt>MDIConfig</tt> object that describes the current configuration of
109          all internal frames. This object can be serialized and reactivated with
110          <tt>readMDIConfig</tt>.
111          @return the <tt>MDIConfig</tt> object
112      */

113     protected MDIConfig createMDIConfig() {
114
115         MDIConfig config = new MDIConfig();
116         java.util.List JavaDoc openFrames = desktopManager.getOpenFrames();
117         List JavaDoc internalFrameDescs = new ArrayList(openFrames.size());
118
119         for (int i = 0; i < openFrames.size(); i++) {
120
121             BasicInternalFrame internalFrame = (BasicInternalFrame)openFrames.get(i);
122
123             Rectangle bounds = internalFrame.getNormalBounds();
124             MDIConfig.InternalFrameDesc internalFrameDesc = new MDIConfig.InternalFrameDesc();
125             internalFrameDesc.setClassName(internalFrame.getClass().getName());
126             internalFrameDesc.setInitParam(internalFrame.getInitParam());
127             internalFrameDesc.setX(bounds.x);
128             internalFrameDesc.setY(bounds.y);
129             internalFrameDesc.setWidth(bounds.width);
130             internalFrameDesc.setHeight(bounds.height);
131             internalFrameDesc.setMaximized(internalFrame.isMaximum());
132             internalFrameDesc.setIconified(internalFrame.isIcon());
133
134             if (internalFrame == desktopPane.getSelectedFrame()) {
135                 config.setActiveFrameDesc(internalFrameDesc);
136             }
137             internalFrameDescs.add(internalFrameDesc);
138
139         }
140         config.setInternalFrameDescs(internalFrameDescs);
141
142         return config;
143     }
144
145     /**
146          Takes an <tt>MDIConfig</tt> object that describes a configuration of
147          internal frames and populates the MDI frame with this configuration.
148          @param config the <tt>MDIConfig</tt> object to be read
149      */

150     protected void readMDIConfig(MDIConfig config) {
151
152         boolean anyFrameMaximized = false;
153         Iterator it = config.getInternalFrameDescs().iterator();
154         while (it.hasNext()) {
155             MDIConfig.InternalFrameDesc internalFrameDesc = (MDIConfig.InternalFrameDesc)it.next();
156
157
158             Constructor JavaDoc frameConstructor;
159             try {
160                 Class JavaDoc frameClass = Class.forName(internalFrameDesc.getClassName());
161                 frameConstructor = frameClass.getConstructor(getFrameConstructorArguments(frameClass));
162             } catch (ClassNotFoundException JavaDoc ex) {
163                 System.out.println("class not found:" + ex.getMessage());
164                 continue;
165             } catch (NoSuchMethodException JavaDoc ex) {
166                 System.out.println("constructor not found:" + ex.getMessage());
167                 continue;
168             }
169
170             BasicInternalFrame frame;
171             try {
172                 frame = (BasicInternalFrame)frameConstructor.newInstance(new Object JavaDoc[] {desktopManager, internalFrameDesc.getInitParam()});
173             } catch (Exception JavaDoc ex) {
174                 ex.printStackTrace();
175                 Throwable JavaDoc cause = ex.getCause();
176                 if (cause != null) {
177                     ex.printStackTrace();
178                 }
179                 continue;
180             }
181             desktopManager.resizeFrame(
182                     frame,
183                     internalFrameDesc.getX(),
184                     internalFrameDesc.getY(),
185                     internalFrameDesc.getWidth(),
186                     internalFrameDesc.getHeight()
187             );
188
189             boolean frameMaximized = internalFrameDesc.isMaximized();
190             anyFrameMaximized = anyFrameMaximized || frameMaximized;
191
192             try {
193                 if (frameMaximized || anyFrameMaximized) {
194                     frame.setMaximum(true);
195                 } else if (internalFrameDesc.isIconified()) {
196                     frame.setIcon(true);
197                 }
198             } catch (PropertyVetoException JavaDoc ex) {
199             }
200
201             if (internalFrameDesc == config.getActiveFrameDesc()) {
202                 desktopManager.setActiveFrame(frame);
203             }
204         }
205
206         desktopManager.showAll();
207     }
208
209     /**
210         Get the constructor arguments classes for the constructor of the supplied frame class.
211         @param frameClass the frame class.
212         @return the constructor argument classes.
213      */

214     protected Class JavaDoc[] getFrameConstructorArguments(Class JavaDoc frameClass) {
215         return BasicInternalFrame.CONSTRUCTOR_ARGUMENTS;
216     }
217
218     private void setupActions() {
219
220         actionNextWindow = new WindowAction("Next window");
221         actionNextWindow.putValue(Action.SHORT_DESCRIPTION,
222                                   "Cycle to the next opened window");
223         actionNextWindow.setEnabled(false);
224         
225         actionPreviousWindow = new WindowAction("Previous window");
226         actionPreviousWindow.putValue(Action.SHORT_DESCRIPTION,
227                                      "Cycle to the previous opened window");
228         actionPreviousWindow.setEnabled(false);
229         
230         actionTileWindows = new WindowAction("Tile windows");
231         actionTileWindows.putValue(Action.SHORT_DESCRIPTION,
232                                    "Tile all windows in the main frame");
233         actionTileWindows.setEnabled(false);
234
235         actionStackWindows = new WindowAction("Stack windows");
236         actionStackWindows.putValue(Action.SHORT_DESCRIPTION,
237                                     "Stack all windows in the main frame");
238         actionStackWindows.setEnabled(false);
239     }
240
241     private void setupMenu() {
242
243         menuWindow = new JMenu("Window");
244             menuWindow.add(actionPreviousWindow).setAccelerator(
245                 KeyStroke.getKeyStroke(KeyEvent.VK_F2, Event.CTRL_MASK));
246             menuWindow.add(actionNextWindow).setAccelerator(
247                 KeyStroke.getKeyStroke(KeyEvent.VK_F3, Event.CTRL_MASK));
248             menuWindow.add(actionTileWindows);
249             menuWindow.add(actionStackWindows);
250     }
251
252     private void setupFrame() {
253
254         setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
255         
256         Container contentPane = getContentPane();
257         contentPane.setLayout(new BorderLayout(5,5));
258         contentPane.add(buildDesktop(), BorderLayout.CENTER);
259         
260     }
261
262     private void setupEventHandlers() {
263
264         addWindowListener(new WindowAdapter() {
265             public void windowClosing(WindowEvent event) {
266                 doQuit();
267             }
268         });
269
270         addComponentListener(new ComponentAdapter() {
271             public void componentResized(ComponentEvent event) {
272                 desktopManager.checkResizeInMaximizedState();
273                 recordLastNormalFrameBounds();
274             }
275             public void componentMoved(ComponentEvent event) {
276                 recordLastNormalFrameBounds();
277             }
278         });
279
280     }
281
282     private void saveWindowSettings() {
283
284         Preferences JavaDoc preferences = Preferences.userNodeForPackage(getClass());
285
286         boolean maximized = (getExtendedState() & MAXIMIZED_BOTH) != 0;
287         preferences.putBoolean(SETTINGS_WINDOW_MAXIMIZED, maximized);
288         Rectangle frameBounds = maximized ? lastNormalFrameBounds : getBounds();
289
290         if (frameBounds != null) {
291             preferences.putInt(SETTINGS_WINDOW_WIDTH, frameBounds.width);
292             preferences.putInt(SETTINGS_WINDOW_HEIGHT, frameBounds.height);
293             preferences.putInt(SETTINGS_WINDOW_X, frameBounds.x);
294             preferences.putInt(SETTINGS_WINDOW_Y, frameBounds.y);
295         }
296     }
297
298     private void loadWindowSettings() {
299
300         Preferences JavaDoc preferences = Preferences.userNodeForPackage(getClass());
301         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
302         Rectangle screenBounds = new Rectangle(screenSize);
303
304         int windowX = preferences.getInt(SETTINGS_WINDOW_X, (int)(screenSize.getWidth() - DEFAULT_WINDOW_WIDTH)/2);
305         int windowY = preferences.getInt(SETTINGS_WINDOW_Y, (int)(screenSize.getHeight() - DEFAULT_WINDOW_HEIGHT)/2);
306         int windowWidth = preferences.getInt(SETTINGS_WINDOW_WIDTH, DEFAULT_WINDOW_WIDTH);
307         int windowHeight = preferences.getInt(SETTINGS_WINDOW_HEIGHT, DEFAULT_WINDOW_HEIGHT);
308
309         Rectangle frameBounds = new Rectangle(windowX, windowY, windowWidth, windowHeight);
310
311         // sanitize frame bounds
312
frameBounds.translate(-Math.min(0, frameBounds.x), -Math.min(0, frameBounds.y));
313         frameBounds.translate(-Math.max(0, frameBounds.x + frameBounds.width - screenSize.width), -Math.max(0, frameBounds.y + frameBounds.height- screenSize.height));
314         frameBounds = screenBounds.intersection(frameBounds);
315
316         setBounds(frameBounds);
317
318         if (preferences.getBoolean(SETTINGS_WINDOW_MAXIMIZED, false)) {
319             setExtendedState(MAXIMIZED_BOTH);
320         }
321
322     }
323
324     private void recordLastNormalFrameBounds() {
325         if ((getExtendedState() & MAXIMIZED_BOTH) == 0) {
326             Rectangle frameBounds = getBounds();
327             if (frameBounds.getX() >= 0 && frameBounds.getY() >= 0) {
328                 lastNormalFrameBounds = frameBounds;
329             }
330         }
331
332     }
333
334     private JComponent buildDesktop() {
335
336         desktopPane = new JDesktopPane();
337         desktopManager = createDesktopManager();
338         desktopPane.setDesktopManager(desktopManager);
339         scpDesktop = new JScrollPane(desktopPane);
340         GUIHelper.setDefaultScrollbarUnits(scpDesktop);
341
342         return scpDesktop;
343     }
344     
345     private class WindowAction extends AbstractAction {
346
347         private WindowAction(String JavaDoc name) {
348             super(name);
349         }
350
351         public void actionPerformed(ActionEvent ev) {
352
353             if (this == actionPreviousWindow) {
354                 desktopManager.cycleToPreviousWindow();
355             } else if (this == actionNextWindow) {
356                 desktopManager.cycleToNextWindow();
357             } else if (this == actionTileWindows) {
358                 desktopManager.tileWindows();
359             } else if (this == actionStackWindows) {
360                 desktopManager.stackWindows();
361             }
362
363         }
364     }
365
366 }
367
Popular Tags