KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > swingwt > awt > Container


1 /*
2    SwingWT
3    Copyright(c)2003-2004, R. Rawson-Tetley
4
5    For more information on distributing and using this program, please
6    see the accompanying "COPYING" file.
7
8    Contact me by electronic mail: bobintetley@users.sourceforge.net
9
10    $Log: Container.java,v $
11    Revision 1.47 2004/05/07 12:11:15 bobintetley
12    Default layout fixes and correct behaviour for null layout
13
14    Revision 1.46 2004/05/06 16:45:44 laurentmartelli
15    Fixed getMaximumSize() compil bug
16
17    Revision 1.45 2004/05/06 16:16:08 laurentmartelli
18    Use layout manager for getMinimumSize(), getMaximumSize() and getPreferredSize()
19
20    Revision 1.44 2004/05/05 23:32:29 laurentmartelli
21    Fixed add(String,Component) to call add(Component,Object)
22
23    Revision 1.43 2004/05/05 13:24:30 bobintetley
24    Bugfixes and Laurent's patch for binary compatibility on Container.add()
25
26    Revision 1.42 2004/05/05 12:43:19 bobintetley
27    Patches/new files from Laurent Martell
28
29    Revision 1.41 2004/05/04 00:57:03 dannaab
30    Sun java and javax package naming improvements. Fix ambiguous class names by hardcoding SWT full class name
31
32    Revision 1.40 2004/05/03 20:53:43 dannaab
33    small tweak to layoutmanager instance objects to make easier to read
34
35    Revision 1.39 2004/04/28 07:19:29 bobintetley
36    Fixes to destruction code
37
38    Revision 1.38 2004/04/27 06:37:42 bobintetley
39    Corrected hierarchy with JComponent descending Container
40
41    Revision 1.37 2004/04/23 00:52:31 dannaab
42    Handle borders in a Swing-like way. Implement EmptyBorder & TitledBorder
43
44    Revision 1.36 2004/03/31 08:07:34 bobintetley
45    JTable bug fixed that prevented it redrawing after being dropped from
46    a container. Protected component method allows catching of when a component
47    is removed from a container.
48
49    Revision 1.35 2004/03/22 15:10:21 bobintetley
50    JRootPane and JLayeredPane implementation
51
52    Revision 1.34 2004/03/12 19:59:47 bobintetley
53    Fix to container remove() that allows recreation of components
54
55    Revision 1.33 2004/03/12 11:05:23 bobintetley
56    Fixed memory leak in container destruction
57
58    Revision 1.32 2004/02/03 09:21:20 bobintetley
59    Fixed threading bug in invokeIn, and JComboBox hotkeys
60
61    Revision 1.31 2004/02/02 12:36:36 bobintetley
62    Proper JScrollPane/ScrollBar implementation
63
64    Revision 1.30 2004/01/30 09:21:55 bobintetley
65    Container bug fixed that caused problems with layout
66
67    Revision 1.29 2004/01/27 11:06:09 bobintetley
68    Fixed bugs in dropping/re-adding the same components
69
70    Revision 1.28 2004/01/26 14:26:29 bobintetley
71    Container/Component Listener/Event support
72
73    Revision 1.27 2004/01/26 08:10:59 bobintetley
74    Many bugfixes and addition of SwingSet
75
76    Revision 1.26 2004/01/16 15:53:32 bobintetley
77    Many compatibility methods added to Container, Component, JInternalFrame,
78       UIManager, SwingUtilities, JTabbedPane, JPasswordField, JCheckBox
79       and JRadioButton.
80
81    Revision 1.25 2004/01/16 09:35:46 bobintetley
82    Full event dispatch thread support!
83
84    Revision 1.24 2004/01/15 15:20:29 bobintetley
85    Java2D work
86
87    Revision 1.23 2004/01/09 11:47:27 bobintetley
88    Automatic JButton mapping!
89
90    Revision 1.22 2004/01/09 10:33:56 bobintetley
91    Changes for JToolBar to allow platform ToolBars, mixed with other components
92
93    Revision 1.21 2004/01/07 09:47:13 bobintetley
94    Fixed class cast exception retrieving component lists
95
96    Revision 1.20 2004/01/05 12:31:13 bobintetley
97    Table/List/Toolbar fixes for correct layout
98
99    Revision 1.19 2004/01/05 11:31:46 bobintetley
100    More layout fixes
101
102    Revision 1.18 2004/01/05 10:09:52 bobintetley
103    Various fixes for new layouts
104
105    Revision 1.17 2004/01/05 08:48:09 bobintetley
106    Manually merged Daniel's changes
107
108    Revision 1.15 2003/12/18 09:37:33 bobintetley
109    Enabled support for JTabbedPane and JClosableTabbedPane (SWT doesn't
110    support, so a bit of magic in here)
111
112    Revision 1.14 2003/12/17 16:30:35 bobintetley
113    Flowlayout fix, vertical toolbar support and cleaned up text alignment
114    hierarchy.
115
116    Revision 1.13 2003/12/17 11:37:46 bobintetley
117    Better GridBag support
118
119    Revision 1.12 2003/12/16 17:46:17 bobintetley
120    Additional thread safety methods
121
122    Revision 1.11 2003/12/16 14:51:16 bobintetley
123    Fixed hang when a window close event closes itself again
124
125    Revision 1.10 2003/12/16 13:14:33 bobintetley
126    Use of SwingWTUtils.isSWTControlAvailable instead of null test
127
128    Revision 1.9 2003/12/16 12:36:07 bobintetley
129    Fix to closing of internal frames
130
131    Revision 1.8 2003/12/16 09:19:02 bobintetley
132    Various small fixes to match Swing more closely
133
134    Revision 1.7 2003/12/15 19:11:09 bobintetley
135    Containers default to FlowLayout unless overriden (as real Swing does)
136
137    Revision 1.6 2003/12/15 18:29:56 bobintetley
138    Changed setParent() method to setSwingWTParent() to avoid conflicts with applications
139
140    Revision 1.5 2003/12/15 17:51:56 bobintetley
141    Revalidate support
142
143    Revision 1.4 2003/12/15 15:54:25 bobintetley
144    Additional core methods
145
146    Revision 1.3 2003/12/14 09:13:38 bobintetley
147    Added CVS log to source headers
148
149 */

150
151
152 package swingwt.awt;
153
154 import java.util.Locale JavaDoc;
155 import java.util.Vector JavaDoc;
156
157 import org.eclipse.swt.SWT;
158 import org.eclipse.swt.widgets.Listener;
159
160 import swingwt.awt.event.ContainerEvent;
161 import swingwtx.swing.SwingUtilities;
162 import swingwtx.swing.SwingWTUtils;
163
164 /**
165  * Any component that can contain other components.
166  * This class maps the Swing layouts/placements to SWT
167  */

168 public class Container extends Component {
169
170     /** The SWT peer this container represents */
171     public org.eclipse.swt.widgets.Composite composite = null;
172
173     /** The layout manager being used to position child components */
174     protected LayoutManager layout = null;
175
176     /** Cache of components waiting to be laid out */
177     protected Vector JavaDoc comps = new Vector JavaDoc();
178
179     protected Vector JavaDoc containerListeners = new Vector JavaDoc();
180     
181     public Dimension getMinimumSize() {
182         return (layout==null) ? super.getMinimumSize() : layout.minimumLayoutSize(this);
183     }
184
185     public Dimension getPreferredSize() {
186         return (layout==null) ? super.getPreferredSize() : layout.preferredLayoutSize(this);
187     }
188
189     public Dimension getMaximumSize() {
190         return (layout instanceof LayoutManager2) ?
191             ((LayoutManager2)layout).maximumLayoutSize(this) :
192             super.getMaximumSize();
193     }
194
195     public void addContainerListener(swingwt.awt.event.ContainerListener l) {
196         containerListeners.add(l);
197     }
198
199     public void removeContainerListener(swingwt.awt.event.ContainerListener l) {
200         containerListeners.remove(l);
201     }
202
203     public Component add(Component c) {
204         return doAdd(c);
205     }
206     
207     public Component add(Component c, int index) {
208         return add(c);
209     }
210
211     /** Actually does the hard work of adding something to a container */
212     public Component doAdd(final Component c) {
213
214         if (c == null) return null;
215         final Container me = this;
216
217         // Don't add it to the cache again if this component is already cached
218
// - this stops us adding the same component twice.
219
if (comps.indexOf(c) == -1) {
220             comps.add(c);
221         }
222
223         if (!SwingWTUtils.isSWTControlAvailable(composite)) return c;
224
225         // Register the comonent with the layout if needed
226
addComponentToLayout(c);
227
228         // Ensure that the setSwingWTParent calls are on the dispatch
229
// thread as they go down - object creation should always be
230
// on this thread
231
SwingUtilities.invokeSync(new Runnable JavaDoc() {
232             public void run() {
233
234                 try {
235                     c.setSwingWTParent(me);
236                     c.setCachedProperties();
237                     c.registerEvents();
238                     processContainerEvent(new swingwt.awt.event.ContainerEvent(me, swingwt.awt.event.ContainerEvent.COMPONENT_ADDED, c));
239                 }
240                 catch (Exception JavaDoc e) {
241                     e.printStackTrace();
242                 }
243
244                 queuedValidate();
245
246             }
247         });
248         return c;
249     }
250
251     protected void processContainerEvent(swingwt.awt.event.ContainerEvent e) {
252         if (containerListeners.size() == 0) return;
253         for (int i = 0; i < containerListeners.size(); i++) {
254             if (e.getID() == ContainerEvent.COMPONENT_ADDED)
255                 ((swingwt.awt.event.ContainerListener) containerListeners.get(i)).componentAdded(e);
256             else
257                 ((swingwt.awt.event.ContainerListener) containerListeners.get(i)).componentRemoved(e);
258         }
259     }
260
261     /**
262      * Adds an existing component to the layout manager
263      */

264     public void addComponentToLayout(Component c) {
265         if (layout != null) {
266             if (layout instanceof LayoutManager2) {
267                 ((LayoutManager2)layout).addLayoutComponent(c, c.layoutModifier);
268             }
269             else
270                 layout.addLayoutComponent(c.getName(), c);
271         }
272     }
273
274     /** Forces laying out of this container's child components again. */
275     public void invalidate() {
276         final Container me = this;
277         if (SwingWTUtils.isSWTControlAvailable(composite))
278             if (layout != null)
279                 SwingUtilities.invokeSync(new Runnable JavaDoc() {
280                     public void run() {
281                         layout.layoutContainer(me);
282                     }
283                 });
284     }
285
286     /** Forces laying out of this container's child components again. */
287     public void validate() { invalidate(); }
288     /** Forces laying out of this container's child components again. */
289     public void revalidate() { invalidate(); }
290
291     /**
292      * Attempts to ensure that a request to layout a container is only
293      * done once whilst adding many components to a container. What we do is
294      * basically set a flag to say we need to relayout the container, and if further
295      * requests come in the next 50ms, we ignore them. This should really take the heat
296      * off the CPU whilst building containers with many objects.
297      *
298      * Since this generally gets called as we work down the tree doing setSwingWTParent
299      * calls, that thread will basically block with no invalidation until all
300      * components have been added (what we want) - this is just horribly complex to
301      * get your head round, but it works :-)
302      *
303      * @author Robin Rawson-Tetley
304      */

305     public void queuedValidate() {
306         if (queuedValidateRequest) return; // Already waiting - don't do anything
307
queuedValidateRequest = true;
308          SwingUtilities.invokeIn(new Runnable JavaDoc() {
309              public void run() {
310                  invalidate();
311                  queuedValidateRequest = false;
312              }
313          }, 1);
314     }
315     protected boolean queuedValidateRequest = false;
316
317     /**
318      * Addition for layouts requiring object based modifiers
319      */

320     public void add(swingwt.awt.Component c, Object JavaDoc layoutModifier) {
321         if (c == null) return;
322         c.layoutModifier = layoutModifier;
323         doAdd(c);
324     }
325     
326     public void add(swingwt.awt.Component c, Object JavaDoc layoutModifier, int index) {
327         add(c, layoutModifier);
328     }
329
330     public Component add(String JavaDoc name, swingwt.awt.Component c) {
331         add(c,name);
332         return c;
333     }
334
335     public void dispose() {
336
337         // Dispose of all child components (and their components)
338
if (comps != null) {
339             for (int i = 0; i < comps.size(); i++) {
340                 try {
341                     ((Component) comps.get(i)).dispose();
342                 }
343                 catch (Exception JavaDoc e) {}
344             }
345             // Ditch the cache
346
comps.removeAllElements();
347         }
348
349         if (peer != null) super.dispose();
350         
351     composite = null;
352     peer = null;
353     }
354
355     /**
356      * Removes a component from the the container
357      * by destroying the peer.
358      */

359     public void remove(swingwt.awt.Component c) {
360         comps.remove(c);
361         layout.removeLayoutComponent(c);
362         c.componentOnlyDispose();
363         c.setComponentRemoved();
364         processContainerEvent(new swingwt.awt.event.ContainerEvent(this, swingwt.awt.event.ContainerEvent.COMPONENT_REMOVED, c));
365         invalidate();
366     }
367
368     public void remove(int index) {
369         Component c = (Component) comps.get(index);
370         remove(c);
371     }
372
373     public void removeAll() {
374         for (int i = 0; i < comps.size(); i++) {
375             Component c = (Component) comps.get(i);
376         remove(c);
377         }
378         comps.removeAllElements();
379         invalidate();
380     }
381
382     /** Removes a cached component only */
383     public void removeComponentFromCache(Component c) {
384         comps.remove(c);
385     }
386
387     /** Returns the layout used by this container */
388     public LayoutManager getLayout() {
389             return layout;
390     }
391
392     /**
393      * I'm totally re-writing this method. No longer
394      * will it only mirror the layouts. From now on,
395      * it will actually use the layout managers to layout
396      * the component, not the mirrored SWT layouts.
397      * Two big advantages with this approach. (a) It
398      * allows custom layout managers. (b) It means
399      * less work since we don't have to port anything.
400      * (yea!)
401      *
402      * @author Daniel Spiewak
403      */

404     public void setLayout(LayoutManager l) {
405         setLayoutImpl(l);
406     }
407
408     /**
409      * The actual code that handles assignment of the
410      * layout manager.
411      *
412      * Separated out as setLayout will often get
413      * subclassed and my head will explode if I don't
414      * do something like this :-)
415      */

416     protected void setLayoutImpl(LayoutManager l) {
417         layout = l;
418
419         if (composite == null)
420                 return;
421
422         SwingUtilities.invokeSync(new Runnable JavaDoc() {
423             public void run() {
424
425                 // we don't want an SWT layout since we will control the layout ourselves
426
composite.setLayout(null);
427
428                 // add a resize listener to let us know when to invalidate the layout
429
composite.addListener(SWT.Resize, new Listener() {
430                         public void handleEvent(org.eclipse.swt.widgets.Event e) {
431                                 invalidate();
432                         }
433                 });
434
435             }
436         });
437     }
438
439     /** Returns the SWT peer being used for this container */
440     public org.eclipse.swt.widgets.Composite getComposite() {
441         return composite;
442     }
443
444     public Container getParent() {
445         return parent;
446     }
447
448     /** Called when this gets added. We can set layouts and things
449      * then if necessary. Note that subclasses are responsible
450      * for creating the actual peer and setting the protected
451      * "composite" variable */

452     public void setSwingWTParent(swingwt.awt.Container parent) throws Exception JavaDoc {
453
454         if (layout != null)
455             setLayoutImpl(layout);
456
457         if (comps.size() > 0) {
458             Object JavaDoc[] obs = comps.toArray();
459             for (int i = 0; i < obs.length; i++) {
460                 Component c = (Component) obs[i];
461                 doAdd(c);
462             }
463         }
464     }
465
466     public ComponentOrientation getComponentOrientation() {
467             return ComponentOrientation.getOrientation(Locale.getDefault());
468     }
469
470     public Insets getInsets() {
471         return new Insets(0,0,0,0);
472     }
473
474     public int getComponentCount() {
475         if (composite != null)
476             return composite.getChildren().length;
477         else
478             return comps.size();
479     }
480
481     public Component getComponent(int i) {
482             return (Component) comps.get(i);
483     }
484
485     public Component[] getComponents() {
486         Object JavaDoc[] comp = comps.toArray();
487         Component[] cps = new Component[comp.length];
488         for (int i = 0; i < comp.length; i++) {
489             cps[i] = (Component) comp[i];
490         }
491         return cps;
492     }
493
494     /**
495      * Useful for debugging purposes. Shows this container and
496      * all it's children.
497      */

498     public void debug_showContainmentTree() {
499         System.out.println("Containment Tree: ====================");
500         System.out.println(getClass().getName());
501         xdebug_showChildren(this, 1);
502     }
503     private void xdebug_showChildren(Container c, int level) {
504         final String JavaDoc SPACE = " ";
505         for (int i = 0; i < c.comps.size(); i++) {
506             Component d = (Component) c.comps.get(i);
507             System.out.println(SPACE.substring(0, level) + d.getClass().getName());
508             if (d instanceof Container)
509                 xdebug_showChildren((Container) d, level+1);
510         }
511     }
512
513 }
514
Popular Tags