comparison usr/src/cmd/krb5/kadmin/gui/visualrt/sunsoft/jws/visual/rt/base/Root.java @ 0:c9caec207d52 b86

Initial porting based on b86
author Koji Uno <koji.uno@sun.com>
date Tue, 02 Jun 2009 18:56:50 +0900
parents
children 1a15d5aaf794
comparison
equal deleted inserted replaced
-1:000000000000 0:c9caec207d52
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 "@(#)Root.java 1.2 05/06/08 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 */
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
116 protected String getUserTypeName() {
117 return (/* NOI18N */"root");
118 }
119
120 /**
121 * Sets the loaded root flag for this root.
122 */
123 void setLoadedRoot(boolean flag) {
124 isLoadedRoot = flag;
125 }
126
127 /**
128 * Returns the value of the loaded root flag.
129 */
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 */
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 */
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 */
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 */
234 void removeRootObserver(RootObserver observer) {
235 if (observer == null)
236 return;
237
238 observers.remove(observer);
239 }
240
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
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
261 private void observerSelect(AttributeManager mgr) {
262 Enumeration e = observers.elements();
263
264 while (e.hasMoreElements())
265 ((RootObserver)e.nextElement()).select(mgr);
266 }
267
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 */
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 */
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 */
313 boolean isUniqueName(String name, AttributeManager skip) {
314 return isUniqueName(this, name, skip, null);
315 }
316
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 */
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 */
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 */
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 */
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 */
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 //
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
528 public void add(AttributeManager child) {
529 containerHelper.add(child);
530 observerAdd(child);
531 }
532
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
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
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
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
591 public void createChildren() {
592 containerHelper.createChildren();
593 }
594
595 public void reparentChildren() {
596 containerHelper.reparentChildren();
597 }
598
599 public void destroyChildren() {
600 containerHelper.destroyChildren();
601 }
602
603 public AttributeManager getChild(String name) {
604 return (containerHelper.getChild(name));
605 }
606
607 public Enumeration getChildList() {
608 return (containerHelper.getChildList());
609 }
610
611 public int getChildCount() {
612 return (containerHelper.getChildCount());
613 }
614
615 /**
616 * Groups
617 */
618
619 private Group group;
620
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
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 */
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 */
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 */
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
719 public void postMessageToParent(Message msg) {
720 if (group != null && !eventForwardingDisabled)
721 group.postMessage(msg);
722 }
723
724 public void postMessage(Message msg) {
725 if (!handleMessage(msg) && group != null &&
726 !eventForwardingDisabled)
727 group.postMessage(msg);
728 }
729
730 public void postEvent(Message msg) {
731 if (handleMessage(msg))
732 return;
733
734 if (group != null && !eventForwardingDisabled)
735 group.postMessage(msg);
736 }
737
738 void disableEventForwarding() {
739 eventForwardingDisabled = true;
740 }
741
742 void enableEventForwarding() {
743 eventForwardingDisabled = false;
744 }
745
746 public void layoutMode() {
747 super.layoutMode();
748 containerHelper.layoutMode();
749 }
750
751 public void previewMode() {
752 super.previewMode();
753 containerHelper.previewMode();
754 }
755 }