KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > util > swing > ScrollingDesktopManager


1 package net.suberic.util.swing;
2 import javax.swing.*;
3 import java.awt.event.*;
4 import java.lang.reflect.Method JavaDoc;
5
6 /**
7  * <p>
8  * This is a DesktopManager for a JDesktopPane which dynamically resizes
9  * when a JInternalFrame is moved out of the visible portion of the
10  * desktop. This means that all parts of your JInteralFrames will be
11  * available via the ScrollBars at all time.
12  * </p>
13  *
14  * <p>
15  * Currently, to use this class you need to set it as the DesktopManager
16  * of your JDesktopPane, and also register the JDesktopPane and its
17  * JScrollPane with this ScrollingDesktopManager:
18  * </p>
19  *
20  * <pre>
21  * JDesktopPane desktopPane = new JDesktopPane();
22  * JScrollPane scrollPane = new JScrollPane(desktopPane,
23  * JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED,
24  * JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
25  * ScrollingDesktopManager manager = new ScrollingDesktopManager(desktopPane,
26  * scrollPane);
27  * desktopPane.setDesktopManager(manager);
28  * </pre>
29  *
30  * <p>
31  * Note that it only makes sense to use this class with the
32  * SCROLLBAR_AS_NEEDED and SCROLLBAR_ALWAYS options on the JScrollPane.
33  * </p>
34  *
35  * @see javax.swing.JDesktopPane
36  * @see javax.swing.JScrollBar
37  * @see javax.swing.DefaultDesktopManager
38  * @version 1.0 6/28/2000
39  * @author Allen Petersen
40  */

41
42 public class ScrollingDesktopManager extends DefaultDesktopManager
43   implements ContainerListener, AdjustmentListener {
44
45   private JScrollPane scrollPane = null;
46
47   private JDesktopPane pane = null;
48
49   private boolean updating = false;
50
51   private static Integer JavaDoc SIMPLE_SCROLL_MODE;
52
53   /**
54    * <p>
55    * This creates a ScrollingDesktopManager for JDesktopPane pane
56    * in JScrollPane scrollPane.
57    * </p>
58    */

59   public ScrollingDesktopManager(JDesktopPane pane, JScrollPane scrollPane) {
60     super();
61     setDesktopPane(pane);
62     setScrollPane(scrollPane);
63   }
64
65   /**
66    * <p>This extends the behaviour of DefaultDesktopManager by
67    * calling <code>updateDesktopSize()</code> after
68    * completing its action.
69    *
70    * Overrides
71    * <code>javax.swing.DefaultDesktopManager.closeFrame(JInternalFrame f).
72    * </code>
73    */

74   public void closeFrame(JInternalFrame f) {
75     super.closeFrame(f);
76     updateDesktopSize();
77
78     // workaround for bug in jdk 1.5 (sigh)
79
SwingUtilities.invokeLater(new Runnable JavaDoc() {
80         public void run() {
81
82           java.awt.KeyboardFocusManager JavaDoc mgr = java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager();
83           pane.requestFocusInWindow();
84         }
85       });
86   }
87
88   /**
89    * <p>This extends the behaviour of DefaultDesktopManager by
90    * calling <code>updateDesktopSize()</code> after
91    * completing its action.
92    *
93    * Overrides
94    * <code>javax.swing.DefaultDesktopManager.minimizeFrame(JInternalFrame f).
95    * </code>
96    */

97   public void minimizeFrame(JInternalFrame f) {
98     super.minimizeFrame(f);
99     updateDesktopSize();
100
101   }
102
103   /**
104    * <p>This extends the behaviour of DefaultDesktopManager by
105    * calling <code>updateDesktopSize()</code> after
106    * completing its action.
107    *
108    * Overrides
109    * <code>javax.swing.DefaultDesktopManager.iconifyFrame(JInternalFrame f).
110    * </code>
111    */

112   public void iconifyFrame(JInternalFrame f) {
113     super.iconifyFrame(f);
114     updateDesktopSize();
115   }
116
117   /**
118    * <p>This extends the behaviour of DefaultDesktopManager by
119    * calling <code>updateDesktopSize()</code> after
120    * completing its action.
121    *
122    * Overrides
123    * <code>javax.swing.DefaultDesktopManager.deiconifyFrame(JInternalFrame f).
124    * </code>
125    */

126   public void deiconifyFrame(JInternalFrame f) {
127     super.deiconifyFrame(f);
128     updateDesktopSize();
129   }
130
131   /**
132    * <p>This extends the behaviour of DefaultDesktopManager by
133    * calling <code>updateDesktopSize()</code> after
134    * completing its action.
135    *
136    * Overrides
137    * <code>javax.swing.DefaultDesktopManager.endDraggingFrame(JComponent f).
138    * </code>
139    */

140   public void endDraggingFrame(JComponent f) {
141     super.endDraggingFrame(f);
142
143     updateDesktopSize();
144   }
145
146   /**
147    * <p>This extends the behaviour of DefaultDesktopManager by
148    * calling <code>updateDesktopSize()</code> after
149    * completing its action.
150    *
151    * Overrides
152    * <code>javax.swing.DefaultDesktopManager.endResizingFrame(JComponent f).
153    * </code>
154    */

155
156   public void endResizingFrame(JComponent f) {
157     super.endResizingFrame(f);
158     updateDesktopSize();
159   }
160
161   /**
162    * <p>This overrides maximizeFrame() such that it only maximizes to the
163    * size of the Viewport, rather than to the entire size of the
164    * JDesktopPane.</p>
165    *
166    * Overrides
167    * <code>javax.swing.DefaultDesktopManager.maximizeFrame(JInternalFrame f)
168    * </code>
169    */

170   public void maximizeFrame(JInternalFrame f) {
171     if (scrollPane != null) {
172       java.awt.Dimension JavaDoc newSize = scrollPane.getViewport().getSize();
173       pane.setSize(newSize);
174       pane.setPreferredSize(newSize);
175     }
176
177     super.maximizeFrame(f);
178
179   }
180
181   /**
182    * Implements componentRemoved() as an empty method. This is necessary
183    * because, in order to move components between layers, JLayeredPane
184    * removes the component from one layer and then adds it to the other
185    * layer. This can lead to problems, as the desktop may resize and
186    * remove the area where the pane was going to be replaced.
187    *
188    * Fortunately, closeFrame() is called when a JInternalFrame is
189    * actually removed from the JDesktopPane, so it should be safe to
190    * ignore the componentRemoved events.
191    */

192   public void componentRemoved(java.awt.event.ContainerEvent JavaDoc e) {
193     //updateDesktopSize();
194
}
195
196   /**
197    * Implements componentAdded() to call updateDesktopSize().
198    */

199   public void componentAdded(java.awt.event.ContainerEvent JavaDoc e) {
200     updateDesktopSize();
201   }
202
203   /**
204    * Implements adjustmentValueChanged() to call updateDesktopSize().
205    */

206   public void adjustmentValueChanged(java.awt.event.AdjustmentEvent JavaDoc e) {
207     updateDesktopSize();
208   }
209
210   /**
211    * This actually does the updating of the parent JDesktopPane.
212    */

213   public void updateDesktopSize() {
214     if (!updating && scrollPane != null && scrollPane.isShowing()) {
215       updating = true;
216
217       JScrollBar hsb = scrollPane.getHorizontalScrollBar();
218       JScrollBar vsb = scrollPane.getVerticalScrollBar();
219
220       // calculate the min and max locations for all the frames.
221
JInternalFrame[] allFrames = pane.getAllFrames();
222       int min_x = 0, min_y = 0, max_x = 0, max_y = 0;
223       java.awt.Rectangle JavaDoc bounds = null;
224       // add to this the current viewable area.
225

226       if (allFrames.length > 0) {
227         bounds = allFrames[0].getBounds(bounds);
228         min_x = bounds.x;
229         min_y = bounds.y;
230         max_x = bounds.width + bounds.x;
231         max_y = bounds.height + bounds.y;
232         for (int i = 1; i < allFrames.length; i++) {
233           bounds = allFrames[i].getBounds(bounds);
234           min_x = Math.min(min_x, bounds.x);
235           min_y = Math.min(min_y, bounds.y);
236           max_x = Math.max(max_x, bounds.width + bounds.x);
237           max_y = Math.max(max_y, bounds.height + bounds.y);
238         }
239       }
240
241       int windowsWidth = max_x;
242       int windowsHeight = max_y;
243
244       bounds = scrollPane.getViewport().getViewRect();
245       min_x = Math.min(min_x, bounds.x);
246       min_y = Math.min(min_y, bounds.y);
247       max_x = Math.max(max_x, bounds.width + bounds.x);
248       max_y = Math.max(max_y, bounds.height + bounds.y);
249
250
251       if (min_x != 0 || min_y != 0) {
252         for (int i = 0; i < allFrames.length; i++) {
253           allFrames[i].setLocation(allFrames[i].getX() - min_x, allFrames[i].getY() - min_y);
254
255         }
256
257         windowsWidth = windowsWidth - min_x;
258         windowsHeight = windowsHeight - min_y;
259       }
260
261       int hval = hsb.getValue();
262       int vval = vsb.getValue();
263
264       bounds = scrollPane.getViewport().getViewRect();
265       int oldViewWidth = bounds.width + hval;
266       int oldViewHeight = bounds.height + vval;
267
268       int portWidth = scrollPane.getViewport().getSize().width;
269       int portHeight = scrollPane.getViewport().getSize().height;
270
271       java.awt.Dimension JavaDoc dim = pane.getSize();
272       int oldWidth = dim.width;
273       int oldHeight = dim.height;
274
275       pane.setSize(max_x - min_x, max_y - min_y);
276
277       /*********************************/
278
279       int prefWidth = max_x - min_x;
280       int prefHeight = max_y - min_y;
281
282
283       boolean hasVsb = false, needsVsb = false, hasHsb = false, needsHsb = false;
284       // if a scrollbar is added, check to see if the space covered
285
// by the scrollbar is whitespace or not. if not, remove that
286
// whitespace from the preferredsize.
287

288       if (vsb.isVisible()) {
289         hasVsb = true;
290       } else {
291         hasVsb = false;
292       }
293
294       if (hsb.isVisible()) {
295         hasHsb = true;
296       } else {
297         hasHsb = false;
298       }
299
300       if (max_x - min_x > scrollPane.getViewport().getViewRect().width)
301         needsHsb = true;
302       else
303         needsHsb = false;
304
305       if (max_y - min_y > scrollPane.getViewport().getViewRect().height)
306         needsVsb = true;
307       else
308         needsVsb = false;
309
310       if (hasVsb == false && needsVsb == true) {
311         if (windowsWidth < bounds.width + bounds.x - vsb.getPreferredSize().width) {
312           prefWidth-=vsb.getPreferredSize().width;
313         }
314       } else if (hasVsb == true && needsVsb == false) {
315         if (windowsWidth <= bounds.width + bounds.x) {
316           prefWidth+= vsb.getPreferredSize().width;
317         }
318       }
319
320       if (hasHsb == false && needsHsb == true) {
321         if (windowsHeight < bounds.height + bounds.y - hsb.getPreferredSize().height) {
322           prefHeight-=hsb.getPreferredSize().height;
323         }
324       } else if (hasHsb == true && needsHsb == false) {
325         if (windowsHeight <= bounds.height + bounds.y) {
326           prefHeight+= hsb.getPreferredSize().height;
327         }
328       }
329
330       /**************************************/
331
332       pane.setPreferredSize(new java.awt.Dimension JavaDoc(prefWidth, prefHeight));
333       scrollPane.validate();
334
335       hsb = scrollPane.getHorizontalScrollBar();
336       vsb = scrollPane.getVerticalScrollBar();
337
338       if (min_x != 0 && hval - min_x + hsb.getModel().getExtent() > hsb.getMaximum()) {
339         hsb.setMaximum(hval - min_x + hsb.getModel().getExtent());
340       }
341
342       if (min_y != 0 && vval - min_y + vsb.getModel().getExtent() > vsb.getMaximum()) {
343         vsb.setMaximum(vval - min_y + vsb.getModel().getExtent());
344       }
345
346       hsb.setValue(hval - min_x);
347
348       vsb.setValue(vval - min_y);
349
350       updating = false;
351     }
352   }
353
354   /**
355    * This sets the scrollPane object. It also removes this as a
356    * listener on the previous scrollPane object (if any), and then sets
357    * it as an adjustmentListener on the scrollPane's JScrollBars.
358    */

359   public void setScrollPane(JScrollPane newScrollPane) {
360     if (scrollPane != null) {
361       scrollPane.getHorizontalScrollBar().removeAdjustmentListener(this);
362       scrollPane.getVerticalScrollBar().removeAdjustmentListener(this);
363     }
364     scrollPane = newScrollPane;
365     scrollPane.getHorizontalScrollBar().addAdjustmentListener(this);
366     scrollPane.getVerticalScrollBar().addAdjustmentListener(this);
367   }
368
369   public JScrollPane getScrollPane() {
370     return scrollPane;
371   }
372
373   /**
374    * This sets the desktopPane object. It also removes this as a
375    * listener on the previous desktopPane object (if any), and then sets
376    * itself as a ContainerListener on the new JDesktopPane.
377    */

378   public void setDesktopPane(JDesktopPane newDesktopPane) {
379     if (pane != null)
380       pane.removeContainerListener(this);
381     pane = newDesktopPane;
382     pane.addContainerListener(this);
383   }
384
385   public JDesktopPane getDesktopPane() {
386     return pane;
387   }
388 }
389
390
391
Popular Tags