KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > wings > SContainer


1 /*
2  * $Id: SContainer.java,v 1.15 2005/05/27 12:51:29 blueshift Exp $
3  * Copyright 2000,2005 wingS development team.
4  *
5  * This file is part of wingS (http://www.j-wings.org).
6  *
7  * wingS is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1
10  * of the License, or (at your option) any later version.
11  *
12  * Please see COPYING for the complete licence.
13  */

14 package org.wings;
15
16 import org.wings.event.SContainerEvent;
17 import org.wings.event.SContainerListener;
18 import org.wings.plaf.ContainerCG;
19 import org.wings.style.CSSProperty;
20 import org.wings.style.CSSSelector;
21 import org.wings.util.ComponentVisitor;
22
23 import java.util.ArrayList JavaDoc;
24 import java.util.Iterator JavaDoc;
25
26
27 /**
28  * This is a container which can hold several other <code>SComponents</code>.
29  *
30  * @author <a HREF="mailto:haaf@mercatis.de">Armin Haaf</a>
31  * @version $Revision: 1.15 $
32  * @see SLayoutManager
33  * @see SComponent
34  */

35 public class SContainer extends SComponent {
36     /**
37      * The layout for the component.
38      */

39     protected SLayoutManager layout;
40
41     /**
42      * background image, that is rendered for this container.
43      */

44     private SIcon backgroundImage;
45
46     /**
47      * The components in this container.
48      */

49     private ArrayList JavaDoc componentList;
50
51     /**
52      * The constraints for the components.
53      */

54     private ArrayList JavaDoc constraintList;
55
56     /**
57      * A Pseudo selector addressing the container area of this container.
58      * Refer to {@link SComponent#setAttribute(org.wings.style.CSSSelector, org.wings.style.CSSProperty, String)}
59      */

60     public static final CSSSelector.Pseudo SELECTOR_CONTENT = new CSSSelector.Pseudo("area of container content");
61
62
63     /**
64      * creates a new container with the given layout
65      *
66      * @param l the layout for this container
67      */

68     public SContainer(SLayoutManager l) {
69         setLayout(l);
70     }
71
72     /**
73      * creates a new container with no layout manager, i.e. the components
74      * are simply written in the same order they were added.
75      */

76     public SContainer() {}
77
78
79     public void updateCG() {
80         super.updateCG();
81
82         if (layout != null)
83             layout.updateCG();
84     }
85
86     /**
87      * Sets a new layout manager.
88      *
89      * @param l new layout manager
90      */

91     public void setLayout(SLayoutManager l) {
92         if (layout != null) {
93             for (int i = 0; i < getComponentCount(); i++) {
94                 layout.removeComponent(getComponent(i));
95             }
96             layout.setContainer(null);
97         }
98
99         layout = l;
100
101         if (layout != null) {
102             for (int i = 0; i < getComponentCount(); i++) {
103                 layout.addComponent(getComponent(i), getConstraintAt(i), i);
104             }
105
106             layout.setContainer(this);
107         }
108     }
109
110     /**
111      * Set the background image.
112      *
113      * @param icon the SIcon representing the background image.
114      */

115     public void setBackgroundImage(SIcon icon) {
116         backgroundImage = icon;
117         setAttribute(SELECTOR_CONTENT, CSSProperty.BACKGROUND_IMAGE, icon);
118     }
119
120     /**
121      * return the background image for this frame.
122      *
123      * @return the background image as SIcon.
124      */

125     public SIcon getBackgroundImage() {
126         return backgroundImage;
127     }
128
129     /**
130      * Returns the current layout
131      *
132      * @return current layout
133      */

134     public SLayoutManager getLayout() {
135         return layout;
136     }
137
138     /**
139      * Adds the specified container listener to receive container events
140      * from this container.
141      * If l is null, no exception is thrown and no action is performed.
142      *
143      * @param l the container listener
144      */

145     public void addContainerListener(SContainerListener l) {
146         addEventListener(SContainerListener.class, l);
147     }
148
149     /**
150      * Removes the specified container listener so it no longer receives
151      * container events from this container.
152      * If l is null, no exception is thrown and no action is performed.
153      *
154      * @param l the container listener
155      */

156     public void removeContainerListener(SContainerListener l) {
157         removeEventListener(SContainerListener.class, l);
158     }
159
160     protected void fireContainerEvent(int type, SComponent comp) {
161         SContainerEvent event = null;
162
163         Object JavaDoc[] listeners = getListenerList();
164         for (int i = listeners.length - 2; i >= 0; i -= 2) {
165             if (listeners[i] == SContainerListener.class) {
166                 // Lazily create the event:
167
if (event == null)
168                     event = new SContainerEvent(this, type, comp);
169
170                 processContainerEvent((SContainerListener) listeners[i + 1],
171                         event);
172             }
173         }
174     }
175
176     /**
177      * Processes container events occurring on this container by
178      * dispatching them to any registered ContainerListener objects.
179      * NOTE: This method will not be called unless container events
180      * are enabled for this component; this happens when one of the
181      * following occurs:
182      * a) A ContainerListener object is registered via addContainerListener()
183      * b) Container events are enabled via enableEvents()
184      *
185      * @param e the container event
186      */

187     protected void processContainerEvent(SContainerListener listener,
188                                          SContainerEvent e) {
189         switch (e.getID()) {
190             case SContainerEvent.COMPONENT_ADDED:
191                 listener.componentAdded(e);
192                 break;
193
194             case SContainerEvent.COMPONENT_REMOVED:
195                 listener.componentRemoved(e);
196                 break;
197         }
198     }
199
200     protected ArrayList JavaDoc getComponentList() {
201         if (componentList == null) {
202             componentList = new ArrayList JavaDoc(3);
203         }
204         return componentList;
205     }
206
207     protected ArrayList JavaDoc getConstraintList() {
208         if (constraintList == null)
209             constraintList = new ArrayList JavaDoc(3);
210         return constraintList;
211     }
212
213
214     /**
215      * returns the number of components in this container
216      *
217      * @return number of components
218      */

219     public int getComponentCount() {
220         return getComponentList().size();
221     }
222
223
224
225     /**
226      * returns the component at the given position
227      *
228      * @param i position
229      * @return component at given pos
230      */

231     public SComponent getComponent(int i) {
232         return (SComponent) getComponentList().get(i);
233     }
234
235     public SComponent[] getComponents() {
236         // vorsichtig mit Threads ( eigentlich TreeLock!!!)
237
return (SComponent[]) getComponentList().toArray(new SComponent[getComponentCount()]);
238     }
239
240
241     /**
242      * returns the constraint for the given component position
243      *
244      * @param i position
245      * @return constraint for component at given position
246      */

247     public Object JavaDoc getConstraintAt(int i) {
248         return getConstraintList().get(i);
249     }
250
251
252
253     /**
254      * Removes the given component from the container.
255      *
256      * @param c the component to remove
257      * @see #remove(org.wings.SComponent)
258      */

259     public void remove(SComponent c) {
260         if (c == null) return;
261
262         if (layout != null)
263             layout.removeComponent(c);
264
265         int index = getComponentList().indexOf(c);
266         if (getComponentList().remove(c)) {
267             getConstraintList().remove(index);
268
269             fireContainerEvent(SContainerEvent.COMPONENT_REMOVED, c);
270
271             c.setParent(null);
272             reload();
273         }
274     }
275
276     /**
277      * Removes the component at the given position from the container.
278      *
279      * @param index remove the component at position <i>index</i>
280      * from this container
281      */

282     public void remove(int index) {
283         SComponent c = getComponent(index);
284         remove(c);
285     }
286
287     /**
288      * Removes all components from the container.
289      */

290     public void removeAll() {
291         while (getComponentCount() > 0) {
292             remove(0);
293         }
294     }
295
296
297     /**
298      * Adds a component to the container with null constraint at the end
299      * of the internal list.
300      *
301      * @param c the component to add
302      * @return the added component
303      */

304     public SComponent add(SComponent c) {
305         return addComponent(c, null);
306     }
307
308     /**
309      * Adds a component to the container with the given constraint at the end
310      * of the internal list.
311      *
312      * @param c the component to add
313      * @param constraint the constraint for this component
314      */

315     public void add(SComponent c, Object JavaDoc constraint) {
316         addComponent(c, constraint);
317     }
318
319     /**
320      * Adds a component to the container with null constraint at the given
321      * index.
322      *
323      * @param c the component to add
324      * @param index the index of the component
325      * @return the added component
326      */

327     public SComponent add(SComponent c, int index) {
328         return addComponent(c, null, index);
329     }
330
331     /**
332      * Adds a component to the container with the given constraint at
333      * the given index.
334      *
335      * @param c the component to add
336      * @param index the index of the component
337      */

338     public void add(SComponent c, Object JavaDoc constraint, int index) {
339         addComponent(c, constraint, index);
340     }
341
342     /**
343      * Adds a component to the container with null constraint at the end
344      * of the internal list.
345      *
346      * @param c the component to add
347      * @return the added component
348      */

349     public SComponent addComponent(SComponent c) {
350         return addComponent(c, null);
351     }
352
353     /**
354      * Adds a component to the container with the given constraint at the end
355      * of the internal list.
356      *
357      * @param c the component to add
358      * @param constraint the constraint for this component
359      * @return the added component
360      */

361     public SComponent addComponent(SComponent c, Object JavaDoc constraint) {
362         return addComponent(c, constraint, getComponentList().size());
363     }
364
365     /**
366      * Adds a component to the container with the given constraint at
367      * the given index.
368      *
369      * @param c the component to add
370      * @param index the index of the component
371      * @return the added component
372      */

373     public SComponent addComponent(SComponent c, int index) {
374         return addComponent(c, null, index);
375     }
376
377     /**
378      * Adds a component to the container with the given constraint at
379      * the given index.
380      *
381      * @param c the component to add
382      * @param index the index of the component
383      * @return the added component
384      */

385     public SComponent addComponent(SComponent c, Object JavaDoc constraint, int index) {
386         if (c != null) {
387             getComponentList().add(index, c);
388             getConstraintList().add(index, constraint);
389             c.setParent(this);
390
391             if (layout != null) {
392                 layout.addComponent(c, constraint, index);
393             }
394             fireContainerEvent(SContainerEvent.COMPONENT_ADDED, c);
395             reload();
396         }
397
398         return c;
399     }
400
401     /**
402      * Sets the parent frame.
403      *
404      * @param f parent frame
405      */

406     protected void setParentFrame(SFrame f) {
407         if (f != parentFrame) {
408             super.setParentFrame(f);
409             for (int i = 0; i < getComponentCount(); i++) {
410                 getComponent(i).setParentFrame(getParentFrame());
411             }
412         }
413     }
414
415     /**
416      * CAVEAT this did not work yet... We need to clone the layout manager as
417      * well, so SLayoutManager must be Cloneable
418      */

419     public Object JavaDoc clone() {
420         try {
421             SContainer erg = (SContainer) super.clone();
422             // uiuiui, layout manager must be cloned as well,...
423

424             // componentList and constraintList contain references to the
425
// original components / constraints
426
erg.getComponentList().clear();
427             erg.getConstraintList().clear();
428             for (int i = 0; i < getComponentCount(); i++) {
429                 erg.addComponent((SComponent) getComponent(i).clone());
430             }
431             return erg;
432         } catch (Exception JavaDoc e) {
433             e.printStackTrace();
434             return null;
435         }
436     }
437
438     public void setCG(ContainerCG cg) {
439         super.setCG(cg);
440     }
441
442     /**
443      * Invite a ComponentVisitor.
444      * Invokes visit(SContainer) on the ComponentVisitor.
445      *
446      * @param visitor the visitor to be invited
447      */

448     public void invite(ComponentVisitor visitor)
449             throws Exception JavaDoc {
450         visitor.visit(this);
451     }
452
453     /**
454      * Calls the visitor on each SComponent this container has. You might
455      * want to call this in your visitor in visit(SContainer).
456      *
457      * @param visitor an implementation of the {@link ComponentVisitor}
458      * interface.
459      */

460     public void inviteEachComponent(ComponentVisitor visitor)
461             throws Exception JavaDoc {
462         Iterator JavaDoc iterator = getComponentList().iterator();
463         while (iterator.hasNext()) {
464             ((SComponent) iterator.next()).invite(visitor);
465         }
466     }
467
468     public void removeNotify() {
469         Iterator JavaDoc iterator = getComponentList().iterator();
470         while (iterator.hasNext()) {
471             ((SComponent)iterator.next()).removeNotify();
472         }
473         super.removeNotify();
474     }
475
476     public ArrayList JavaDoc getMenus() {
477         ArrayList JavaDoc menus = new ArrayList JavaDoc();
478         if (isVisible()) {
479             Iterator JavaDoc iter = getComponentList().iterator();
480             while (iter.hasNext()) {
481                 SComponent comp = (SComponent)iter.next();
482                 ArrayList JavaDoc compMenus = comp.getMenus();
483                 compMenus.removeAll(menus);
484                 menus.addAll(compMenus);
485             }
486             SPopupMenu pmenu = getComponentPopupMenu();
487             if (pmenu != null && !menus.contains(pmenu)) {
488                 menus.add(pmenu);
489             }
490         }
491         return menus;
492     }
493 }
494
Popular Tags