xref: /titanic_44/usr/src/cmd/krb5/kadmin/gui/visualrt/sunsoft/jws/visual/rt/base/Root.java (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * ident	"%Z%%M%	%I%	%E% SMI"
24  *
25  * Copyright (c) 2000 by Sun Microsystems, Inc.
26  * All rights reserved.
27  */
28 
29 /*
30  *        Copyright (C) 1996  Active Software, Inc.
31  *                  All rights reserved.
32  *
33  * @(#) Root.java 1.88 - last change made 07/25/97
34  */
35 
36 package sunsoft.jws.visual.rt.base;
37 
38 import sunsoft.jws.visual.rt.shadow.java.awt.*;
39 
40 import java.awt.Event;
41 import java.awt.Frame;
42 import java.util.*;
43 
44 /*
45  * NOTE: Whenever a new public or protected variable is added to this
46  * class the name of the variable must be added to the reservedWords
47  * list, so that the user doesn't use it in one of the generated Root
48  * sub-classes.
49  */
50 
51 /**
52  * Instances of the Root class are used for the root of the group's
53  * shadow tree.  The direct child shadows of an instantiation of this
54  * object will typically be top-level windows or the top panel of an
55  * applet.
56  *
57  * @version 1.88, 07/25/97
58  */
59 public class Root extends AttributeManager implements AMContainer {
60 
61     private AMContainerHelper containerHelper = new AMContainerHelper(this);
62 
63     /**
64      * This flag is set to true if this is the loaded root.
65      */
66     private boolean isLoadedRoot = false;
67 
68     /**
69      * The constructor defines the Root's attributes.
70      */
Root()71     public Root() {
72         attributes.add(/* NOI18N */"generateClass",
73 		    /* NOI18N */"java.lang.String", null, 0);
74         attributes.add(/* NOI18N */"generateDirectory",
75 		    /* NOI18N */"java.lang.String", null, 0);
76         attributes.add(/* NOI18N */"generatePackage",
77 		    /* NOI18N */"java.lang.String", null, 0);
78         attributes.add(/* NOI18N */"willGenerateGUI",
79 		    /* NOI18N */"java.lang.Boolean", Boolean.TRUE, 0);
80         attributes.add(/* NOI18N */"willGenerateMain",
81 		    /* NOI18N */"java.lang.Boolean", Boolean.TRUE, 0);
82         attributes.add(/* NOI18N */"willGenerateGroup",
83 		    /* NOI18N */"java.lang.Boolean", Boolean.FALSE, 0);
84         attributes.add(/* NOI18N */"willGenerateHTML",
85 		    /* NOI18N */"java.lang.Boolean", Boolean.FALSE, 0);
86         attributes.add(/* NOI18N */"suffixForGUIClass",
87 		    /* NOI18N */"java.lang.String", /* NOI18N */"Root", 0);
88         attributes.add(/* NOI18N */"suffixForMainClass",
89 		    /* NOI18N */"java.lang.String", /* NOI18N */"Main", 0);
90         attributes.add(/* NOI18N */"suffixForOpsClass",
91 		    /* NOI18N */"java.lang.String", /* NOI18N */"Ops", 0);
92         attributes.add(/* NOI18N */"suffixForGroupClass",
93 		    /* NOI18N */"java.lang.String", /* NOI18N */"", 0);
94         attributes.add(/* NOI18N */"showGenerateConsole",
95 		    /* NOI18N */"java.lang.Boolean", Boolean.TRUE, 0);
96 
97         attributes.add(/* NOI18N */"groupType",
98 		    /* NOI18N */"java.lang.String", null, 0);
99         attributes.add(/* NOI18N */"appletSize",
100 		    /* NOI18N */"java.awt.Dimension", null, 0);
101 
102         /**
103          * When autoNaming is true, new shadows added somewhere
104          * under the
105          * root will automatically be assigned unique names if their
106          * name
107          * attribute is null (see AMContainerHelper.)
108          */
109         attributes.add(/* NOI18N */"autoNaming",
110 		    /* NOI18N */"java.lang.Boolean", Boolean.TRUE,
111 		       HIDDEN | TRANSIENT);
112 
113         set(/* NOI18N */"name", getUniqueName(this));
114     }
115 
getUserTypeName()116     protected String getUserTypeName() {
117         return (/* NOI18N */"root");
118     }
119 
120     /**
121      * Sets the loaded root flag for this root.
122      */
setLoadedRoot(boolean flag)123     void setLoadedRoot(boolean flag) {
124         isLoadedRoot = flag;
125     }
126 
127     /**
128      * Returns the value of the loaded root flag.
129      */
isLoadedRoot()130     public boolean isLoadedRoot() {
131         return isLoadedRoot;
132     }
133 
134     /**
135      * The first child in the children vector is the main container.
136      * To set the main child, we simply move the item to be selected
137      * to the top of the list.
138      *
139      * This method should only called by the builder because this method
140      * assumes that panels are wrapped with a window shadow.
141      */
setMainChild(AttributeManager container, boolean isPanel)142     void setMainChild(AttributeManager container, boolean isPanel) {
143         AttributeManager prev = getMainChild();
144 
145         // menubar should be removed from a frame about to become the
146         // surrounder for a main panel
147         if ((container instanceof FrameShadow) &&
148 	    !((FrameShadow)container).isPanel() &&
149 	    isPanel && container.get(/* NOI18N */"menubar") != null) {
150             container.set(/* NOI18N */"menubar", null);
151         }
152 
153         WindowShadow win = null;
154         WindowShadow prevwin = null;
155 
156         if (container instanceof WindowShadow)
157             win = (WindowShadow)container;
158         if (prev instanceof WindowShadow)
159             prevwin = (WindowShadow)prev;
160 
161         if (prev == container) {
162             if (win != null) {
163                 win.isPanel(isPanel);
164                 win.show();
165             }
166         } else {
167             if (prevwin != null)
168                 prevwin.isPanel(false);
169 
170             // Select the prev so that the NameEditor will
171             // load prev's "title"
172             // attribute.  This way, when we switch off of prev,
173             // prev's title won't
174             // be wiped out by the name editor.
175             observerSelect(prev);
176 
177             if (win != null) {
178                 win.isPanel(isPanel);
179                 win.show();
180             }
181 
182             Vector children = containerHelper.getChildren();
183             if (!children.removeElement(container))
184                 throw new Error(Global.fmtMsg(
185 			"sunsoft.jws.visual.rt.base.Root.RootMissingContainer",
186 					      getName(), container.getName()));
187             children.insertElementAt(container, 0);
188         }
189 
190         observerReload();
191         observerSelect(container);
192     }
193 
194     /**
195      * Returns the main child of the root.  This will typically be
196      * either a window or a panel.
197      */
getMainChild()198     public AttributeManager getMainChild() {
199         Vector children = containerHelper.getChildren();
200         if (children.size() > 0)
201             return (AttributeManager)children.elementAt(0);
202         else
203             return null;
204     }
205 
206     // List of root observers
207     private Hashtable observers = new Hashtable();
208 
209     /**
210      * Registers an observer for this root object.
211      * The observer will receive
212      * updates concerning groups or window shadows that are
213      * added or removed
214      * from this root.
215      */
addRootObserver(RootObserver observer)216     void addRootObserver(RootObserver observer) {
217         if (observer == null)
218             return;
219 
220         if (observers.put(observer, observer) != null)
221             return;
222 
223         observer.clear();
224         Enumeration e = getChildList();
225         while (e.hasMoreElements()) {
226             AttributeManager mgr = (AttributeManager)e.nextElement();
227             observer.add(mgr);
228         }
229     }
230 
231     /**
232      * Unregisters an observer for this root object.
233      */
removeRootObserver(RootObserver observer)234     void removeRootObserver(RootObserver observer) {
235         if (observer == null)
236             return;
237 
238         observers.remove(observer);
239     }
240 
observerAdd(AttributeManager mgr)241     private void observerAdd(AttributeManager mgr) {
242         if (!(mgr instanceof WindowShadow) && !(mgr instanceof Group) &&
243 	    !(mgr instanceof BeanShadow))
244 	    return;
245 
246         Enumeration e = observers.elements();
247         while (e.hasMoreElements())
248             ((RootObserver)e.nextElement()).add(mgr);
249     }
250 
observerRemove(AttributeManager mgr)251     private void observerRemove(AttributeManager mgr) {
252         if (!(mgr instanceof WindowShadow) && !(mgr instanceof Group) &&
253 	    !(mgr instanceof BeanShadow))
254 	    return;
255 
256         Enumeration e = observers.elements();
257         while (e.hasMoreElements())
258             ((RootObserver)e.nextElement()).remove(mgr);
259     }
260 
observerSelect(AttributeManager mgr)261     private void observerSelect(AttributeManager mgr) {
262         Enumeration e = observers.elements();
263 
264         while (e.hasMoreElements())
265             ((RootObserver)e.nextElement()).select(mgr);
266     }
267 
observerReload()268     private void observerReload() {
269         Enumeration e1 = observers.elements();
270 
271         while (e1.hasMoreElements()) {
272             RootObserver observer = (RootObserver)e1.nextElement();
273 
274             observer.clear();
275             Enumeration e2 = containerHelper.getChildren().elements();
276             while (e2.hasMoreElements())
277                 observer.add((AttributeManager)e2.nextElement());
278         }
279     }
280 
281     // Naming children validly and uniquely
282 
283     /**
284      * A table containing ever-increasing counters for unique new names.
285      * Isn't needed in runtime mode, only when the designer is running.
286      */
287     private Hashtable uniqueNameTable = null;
288 
289     /**
290      * Clears the hashtable of unique name counters.
291      * Should only be used when
292      * restarting (user selects "File->New").
293      */
clearUniqueNameTable()294     void clearUniqueNameTable() {
295         uniqueNameTable = null;
296     }
297 
298     /**
299      * Returns true if the name chosen is unique and has not already
300      * been used by one of the descendants of this root object.
301      */
isUniqueName(String name)302     boolean isUniqueName(String name) {
303         return isUniqueName(this, name, null, null);
304     }
305 
306     /**
307      * Returns true if the name chosen is unique and has not already
308      * been used by something under this root.  When encountered, the
309      * "self" object is not compared, so you can also use this function
310      * to test whether the name of an object that is within the tree is
311      * unique unto itself.
312      */
isUniqueName(String name, AttributeManager skip)313     boolean isUniqueName(String name, AttributeManager skip) {
314         return isUniqueName(this, name, skip, null);
315     }
316 
isUniqueName(String name, AttributeManager skip, AttributeManager prune)317     boolean isUniqueName(String name,
318 			 AttributeManager skip, AttributeManager prune) {
319         return isUniqueName(this, name, skip, prune);
320     }
321 
322     /**
323      * Returns true if the name chosen is unique and has not already
324      * been used by one of the descendants of the given AMContainer
325      * object.  When encountered, the "self" object is not compared,
326      * so you can also use this function to test whether the name of an
327      * object that is within the tree is unique unto itself.
328      */
isUniqueName(AttributeManager mgr, String name, AttributeManager skip, AttributeManager prune)329     private boolean isUniqueName(AttributeManager mgr,
330 				 String name,
331 				 AttributeManager skip,
332 				 AttributeManager prune)
333     {
334         if (mgr == prune)
335             return true;
336 
337         if ((mgr != skip) && name.equals(mgr.get(/* NOI18N */"name")))
338             return false;
339 
340         if (mgr instanceof AMContainer) {
341             AMContainer cntr = (AMContainer)mgr;
342             Enumeration e = cntr.getChildList();
343             while (e.hasMoreElements()) {
344                 mgr = (AttributeManager)e.nextElement();
345                 if (!isUniqueName(mgr, name, skip, prune))
346                     return false;
347             }
348         }
349 
350         return true;
351     }
352 
353     /**
354      * The list of reserved words.  The java language reserved words and
355      * also instance variable names already taken in the
356      * AttributeManager or Root classes that cannot be used in names of
357      * objects in the designer.
358      */
359     private static final String reservedWords[] = {
360         /* NOI18N */"abstract", /* NOI18N */"boolean",
361 		    /* NOI18N */"break", /* NOI18N */"byte",
362 		    /* NOI18N */"byvalue",
363 		    /* NOI18N */"case", /* NOI18N */"cast",
364 	    /* NOI18N */"catch", /* NOI18N */"char", /* NOI18N */"class",
365 		    /* NOI18N */"const", /* NOI18N */"continue",
366 		    /* NOI18N */"default", /* NOI18N */"do",
367 		    /* NOI18N */"double", /* NOI18N */"else",
368 		    /* NOI18N */"extends",
369 		    /* NOI18N */"false", /* NOI18N */"final",
370 		    /* NOI18N */"finally", /* NOI18N */"float",
371 		    /* NOI18N */"for", /* NOI18N */"future",
372 		    /* NOI18N */"generic", /* NOI18N */"goto",
373 		    /* NOI18N */"if",
374 		    /* NOI18N */"implements", /* NOI18N */"import",
375 		    /* NOI18N */"inner", /* NOI18N */"instanceof",
376 		    /* NOI18N */"int",
377 		    /* NOI18N */"interface", /* NOI18N */"long",
378 		    /* NOI18N */"native",
379 		    /* NOI18N */"new", /* NOI18N */"null",
380 		    /* NOI18N */"operator", /* NOI18N */"outer",
381 		    /* NOI18N */"package",
382 		    /* NOI18N */"private",
383 		    /* NOI18N */"protected", /* NOI18N */"public",
384 		    /* NOI18N */"rest", /* NOI18N */"return",
385 		    /* NOI18N */"short", /* NOI18N */"static",
386 		    /* NOI18N */"super", /* NOI18N */"switch",
387 		    /* NOI18N */"synchronized", /* NOI18N */"this",
388 		    /* NOI18N */"throw",
389 		    /* NOI18N */"throws",
390 	    /* NOI18N */"transient", /* NOI18N */"true", /* NOI18N */"try",
391 	    /* NOI18N */"var", /* NOI18N */"void", /* NOI18N */"volatile",
392 		    /* NOI18N */"while",
393 		    /* NOI18N */"containerHelper", /* NOI18N */"READONLY",
394 		    /* NOI18N */"HIDDEN", /* NOI18N */"TRANSIENT",
395 		    /* NOI18N */"CONTAINER", /* NOI18N */"attributes",
396 		    /* NOI18N */"parent", /* NOI18N */"isCreated",
397 		    /* NOI18N */"GROUP", /* NOI18N */"ROOT" };
398 
399     // valid characters in variable names
400     // I18N bug
401     //  private static final String
402     // validNameStarters="$abcdefghijklmnopqrstuvwxyz";
403     // private static final String
404     // validNameAnys=validNameStarters + "_0123456789";
405 
406     /**
407      * Returns true if the given name could be legally
408      * placed in generated
409      * code where it would be compiled as a variable name.
410      */
isValidName(String name)411     static boolean isValidName(String name) {
412 	// check that the name isn't blank
413 	if (name == null || name.length() == 0)
414 	    return (false);
415 
416 	// check that the name is not a reserved word (case counts!)
417 	for (int i = 0; i < reservedWords.length; i++)
418 	    if (name.equals(reservedWords[i]))
419                 return (false);
420 	/* JSTYLED */
421 	/*  I18n BUG
422             // check that the name starts with a valid start
423             // character (not a number)
424             String s = name.toLowerCase();
425             if (validNameStarters.indexOf(s.substring(0, 1)) == -1)
426 	    return (false);
427 
428             // check that the rest of the characters in the name
429             // are valid
430             for (int i = 1; i < name.length(); i++)
431 	    if (validNameAnys.indexOf(s.substring(i, i+1)) == -1)
432 	    return (false);
433 	*/
434 
435 	for (int i = 0; i < name.length(); i++) {
436 	    if ((i == 0) &&
437                 (!Character.isJavaIdentifierStart(name.charAt(i))))
438                 return false;
439 	    else
440 		if (!Character.isJavaIdentifierPart(name.charAt(i)))
441                     return false;
442 	}
443 	return (true);
444     }
445 
446     /**
447      * Returns a unique name that can be used for a new
448      * shadow object.
449      * The names are guaranteed to be valid variable names for a
450      * generated Root sub-class later on.
451      */
getUniqueName(AttributeManager child)452     String getUniqueName(AttributeManager child) {
453 	// delayed creation of the table (this routine never
454 	// called in runtime)
455 	if (uniqueNameTable == null)
456 	    uniqueNameTable = new Hashtable();
457 
458 	String type = child.getUserTypeName();
459 	String retval = null;
460 
461 	while (retval == null || !isUniqueName(retval) ||
462 	        !isValidName(retval)) {
463 	    if (uniqueNameTable.containsKey(type)) {
464 		int count = ((Integer)
465 			     uniqueNameTable.get(type)).intValue();
466 		uniqueNameTable.put(type, new Integer(count + 1));
467 		retval = type + Integer.toString(count);
468 	    } else {
469 		uniqueNameTable.put(type, new Integer(2));
470 		retval = type + /* NOI18N */"1";
471 	    }
472 	}
473 	return (retval);
474     }
475 
476     /**
477      * Returns a name that is unique not only within this root,
478      * but within
479      * another as well.  This is useful when merging two roots.
480      */
getUniqueName(AttributeManager child, Root otherTree)481     String getUniqueName(AttributeManager child, Root otherTree) {
482 	// because of the unique name counters, we can repeatedly call
483 	// getUniqueName without getting the same name over again
484 	String newName = getUniqueName(child);
485 	while (!otherTree.isUniqueName(newName))
486 	    newName = getUniqueName(child);
487 	return (newName);
488     }
489 
490     /**
491      * Returns a string describing what is wrong with given
492      * name choice.
493      * The string can be used in an error popup or status bar line.
494      * Null is returned when there is no problem with the name.
495      */
getProblemWithName(String name)496     String getProblemWithName(String name) {
497 	String errorMsg = null;
498 
499 	if (name == null || name.length() == 0)
500 	    errorMsg = Global.getMsg(
501 		    "sunsoft.jws.visual.rt.base.Root.NeedName");
502 	else if (!isUniqueName(name))
503 	    errorMsg = Global.fmtMsg(
504 		    "sunsoft.jws.visual.rt.base.Root.NotUniqueName", name);
505 	else if (!isValidName(name))
506 	    errorMsg = Global.fmtMsg(
507 		    "sunsoft.jws.visual.rt.base.Root.NotValidName", name);
508 
509 	return (errorMsg);
510     }
511 
512     //
513     // Overridden to deal with the special "GROUP" and "ROOT" names.
514     //
resolve(String name)515     public AttributeManager resolve(String name) {
516 	if (name == null)
517 	    return null;
518 	else if (name.equals(/* NOI18N */"GROUP"))
519 	    return group;
520 	else if (name.equals(/* NOI18N */"ROOT"))
521 	    return this;
522 	else
523 	    return super.resolve(name);
524     }
525 
526     // AMContainer interfaces
527 
add(AttributeManager child)528     public void add(AttributeManager child) {
529 	containerHelper.add(child);
530 	observerAdd(child);
531     }
532 
remove(AttributeManager child)533     public void remove(AttributeManager child) {
534 	containerHelper.remove(child);
535 	observerRemove(child);
536     }
537 
538     //
539     // The root's "addChildBody" and "removeChildBody"
540     // methods are only
541     // called when the root has a panel as a child.
542     //  In this case, it should
543     // add the panel as a child of the group's parent.
544     //
545 
addChildBody(Shadow child)546     public void addChildBody(Shadow child) {
547 	// Don't add frames and dialogs to the group's parent
548 	if (child instanceof WindowShadow)
549 	    return;
550 
551 	if (group == null)
552 	    return;
553 
554 	AMContainer parent = group.getParent();
555 	if (parent == null)
556 	    return;
557 
558 	if (child != null && child.getBody() != null)
559 	    parent.addChildBody(child);
560     }
561 
updateContainerAttribute(AttributeManager child, String key, Object value)562     public void updateContainerAttribute(AttributeManager child,
563 					 String key, Object value) {
564 	if (group == null)
565 	    return;
566 
567 	AMContainer parent = (AMContainer)group.getParent();
568 	if (parent == null)
569 	    return;
570 
571 	parent.updateContainerAttribute(child, key, value);
572     }
573 
removeChildBody(Shadow child)574     public void removeChildBody(Shadow child) {
575 	// Don't need to remove frames and dialogs from
576 	// the group's parent
577 	if (child instanceof WindowShadow)
578 	    return;
579 
580 	if (group == null)
581 	    return;
582 
583 	AMContainer parent = group.getParent();
584 	if (parent == null)
585 	    return;
586 
587 	if (child != null && child.getBody() != null)
588 	    parent.removeChildBody(child);
589     }
590 
createChildren()591     public void createChildren() {
592 	containerHelper.createChildren();
593     }
594 
reparentChildren()595     public void reparentChildren() {
596 	containerHelper.reparentChildren();
597     }
598 
destroyChildren()599     public void destroyChildren() {
600 	containerHelper.destroyChildren();
601     }
602 
getChild(String name)603     public AttributeManager getChild(String name) {
604 	return (containerHelper.getChild(name));
605     }
606 
getChildList()607     public Enumeration getChildList() {
608 	return (containerHelper.getChildList());
609     }
610 
getChildCount()611     public int getChildCount() {
612 	return (containerHelper.getChildCount());
613     }
614 
615     /**
616      * Groups
617      */
618 
619     private Group group;
620 
setGroup(Group group)621     public void setGroup(Group group) {
622 	if (this.group != null)
623 	    this.group.removeRootChildren(this);
624 
625 	this.group = group;
626 
627 	if (this.group != null)
628 	    this.group.addRootChildren(this);
629     }
630 
getGroup()631     public Group getGroup() {
632 	return group;
633     }
634 
635     /**
636      * Sets the cursor for all of the root's frames.  This method is
637      * declared package private so that it won't be
638      * confused with the
639      * group's setCursor method.
640      */
setCursor(int cursor)641     void setCursor(int cursor) {
642 	Enumeration e = getChildList();
643 	while (e.hasMoreElements()) {
644 	    AttributeManager mgr = (AttributeManager)e.nextElement();
645 	    if (mgr instanceof FrameShadow) {
646 		FrameShadow fs = (FrameShadow)mgr;
647 		Frame f = (Frame)fs.getBody();
648 
649 		if (f != null) {
650 		    int prevCursor = f.getCursorType();
651 		    if (cursor == prevCursor) {
652 			JAShadowAccess.incrCursor(fs);
653 		    } else if (cursor == Group.RESTORE_CURSOR) {
654 			if (JAShadowAccess.decrCursor(fs) == 0) {
655 			    f.setCursor(
656 					JAShadowAccess.getPrevCursor(fs));
657 			    JAShadowAccess.setPrevCursor(fs,
658 							 Frame.DEFAULT_CURSOR);
659 			}
660 		    } else {
661 			JAShadowAccess.setPrevCursor(fs, prevCursor);
662 			f.setCursor(cursor);
663 			f.getToolkit().sync();
664 		    }
665 		}
666 	    }
667 	}
668     }
669 
670     /**
671      * Maps all the visible children of the root.  Do not call this
672      * method directly.  It is called from the Group class when the
673      * group is shown.
674      */
showRoot()675     public void showRoot() {
676 	AttributeManager mgr;
677 	Enumeration e = getChildList();
678 
679 	while (e.hasMoreElements()) {
680 	    mgr = (AttributeManager)e.nextElement();
681 	    if (mgr instanceof ComponentShadow) {
682 		ComponentShadow comp = (ComponentShadow)mgr;
683 		Boolean v = (Boolean)comp.get(/* NOI18N */"visible");
684 		if (v.booleanValue())
685 		    comp.showComponent();
686 	    } else if (mgr instanceof Group) {
687 		Group group = (Group)mgr;
688 		Boolean v = (Boolean)group.get(/* NOI18N */"visible");
689 		if (v.booleanValue())
690 		    group.internalShowGroup();
691 	    }
692 	}
693     }
694 
695     /**
696      * Unmaps all the children of the root.  Do not call this
697      * method directly.  It is called from the Group class when the
698      * group is hidden.
699      */
hideRoot()700     public void hideRoot() {
701 	AttributeManager mgr;
702 	Enumeration e = getChildList();
703 
704 	while (e.hasMoreElements()) {
705 	    mgr = (AttributeManager)e.nextElement();
706 	    if (mgr instanceof ComponentShadow)
707 		((ComponentShadow)mgr).hideComponent();
708 	    else if (mgr instanceof Group)
709 		((Group)mgr).internalHideGroup();
710 	}
711     }
712 
713     /**
714      * Events
715      */
716 
717     private boolean eventForwardingDisabled;
718 
postMessageToParent(Message msg)719     public void postMessageToParent(Message msg) {
720 	if (group != null && !eventForwardingDisabled)
721 	    group.postMessage(msg);
722     }
723 
postMessage(Message msg)724     public void postMessage(Message msg) {
725 	if (!handleMessage(msg) && group != null &&
726             !eventForwardingDisabled)
727             group.postMessage(msg);
728     }
729 
postEvent(Message msg)730     public void postEvent(Message msg) {
731 	if (handleMessage(msg))
732 	    return;
733 
734 	if (group != null && !eventForwardingDisabled)
735 	    group.postMessage(msg);
736     }
737 
disableEventForwarding()738     void disableEventForwarding() {
739 	eventForwardingDisabled = true;
740     }
741 
enableEventForwarding()742     void enableEventForwarding() {
743 	eventForwardingDisabled = false;
744     }
745 
layoutMode()746     public void layoutMode() {
747 	super.layoutMode();
748 	containerHelper.layoutMode();
749     }
750 
previewMode()751     public void previewMode() {
752 	super.previewMode();
753 	containerHelper.previewMode();
754     }
755 }
756