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 * @(#) ComponentShadow.java 1.82 - last change made 08/05/97
34 */
35
36package sunsoft.jws.visual.rt.shadow.java.awt;
37
38import sunsoft.jws.visual.rt.base.*;
39import sunsoft.jws.visual.rt.awt.GBLayout;
40import sunsoft.jws.visual.rt.awt.GBConstraints;
41import sunsoft.jws.visual.rt.type.AnchorEnum;
42import sunsoft.jws.visual.rt.base.Global;
43
44import java.awt.Component;
45import java.awt.Container;
46import java.awt.Window;
47import java.awt.LayoutManager;
48import java.awt.SystemColor;
49import java.awt.Color;
50import java.awt.Font;
51import java.awt.Frame;
52import java.awt.Panel;
53
54/**
55 * Shadow class that wraps the AWT Component class.  The attributes
56 * available for this class are listed below.  Check the super class
57 * for additional attributes.
58 *
59 * <pre>
60name            type                      default value
61-----------------------------------------------------------------------
62anchor          rt.type.AnchorEnum        center
63background      java.awt.Color            null
64enabled         java.lang.Boolean         true
65font            java.awt.Font             null
66foreground      java.awt.Color            null
67GBConstraints   rt.awt.GBConstraints      new GBConstraints()
68insets          java.awt.Insets           null
69visible         java.lang.Boolean         true
70*  < /pre>
71*
72* All shadow classes(except for the menu-related ones) include the
73* attributes from the ComponentShadow class in addition to their own,
74* and they do so by subclassing it.  This class is a super class and
75* isn't available directly from the palette.
76*
77* @see Component
78* @version 1.75, 05/02/97
79*/
80public class ComponentShadow extends Shadow {
81
82    // Set to true while a show operation is in progress
83    protected boolean doingShow = false;
84
85    ComponentShadow() {
86        GBConstraints c = new GBConstraints();
87        c.gridx = 0;
88        c.gridy = 0;
89        attributes.add(/* NOI18N */"GBConstraints",
90		       /* NOI18N */"sunsoft.jws.visual.rt.awt.GBConstraints",
91		       c, HIDDEN | NONBODY | CONTAINER);
92
93        attributes.add(/* NOI18N */"layoutName",
94		       /* NOI18N */"java.lang.String", null,
95		       HIDDEN | NONBODY | CONTAINER);
96        attributes.add(/* NOI18N */"anchor",
97		       /* NOI18N */"sunsoft.jws.visual.rt.type.AnchorEnum",
98		       new AnchorEnum(GBConstraints.CENTER),
99		    NONBODY | CONTAINER);
100        attributes.add(/* NOI18N */"insets",
101		       /* NOI18N */"java.awt.Insets",
102		    null, NONBODY | CONTAINER);
103
104        attributes.add(/* NOI18N */"visible",
105		       /* NOI18N */"java.lang.Boolean", Boolean.TRUE,
106		       HIDDEN | DEFAULT);
107        attributes.add(/* NOI18N */"enabled",
108		       /* NOI18N */"java.lang.Boolean", Boolean.TRUE, DEFAULT);
109
110        if (Global.isMotif()) {
111            // Default colors should be null for motif since they inherit the
112            // colors from the Containers.
113            attributes.add(/* NOI18N */"foreground",
114			   /* NOI18N */"java.awt.Color",
115			   null, DEFAULT | DONTFETCH);
116            attributes.add(/* NOI18N */"background",
117			   /* NOI18N */"java.awt.Color",
118			   null, DEFAULT | DONTFETCH);
119        } else {
120            // Component bg and fg must be explicitly set for
121            // Windows. Unfortunately, JDK implements setBackground
122            // and setForground the Motif way. That is, if the default
123            // color is null then retrieve the parent's color. This is
124            // not how the peer is implemented. For Windows, the
125            // container's colors are not inherited by the container.
126            attributes.add(/* NOI18N */"foreground",
127			   /* NOI18N */"java.awt.Color",
128			   SystemColor.controlText, DONTFETCH);
129            attributes.add(/* NOI18N */"background",
130			   /* NOI18N */"java.awt.Color",
131			   SystemColor.control, DONTFETCH);
132        }
133        attributes.add(/* NOI18N */"font",
134		       /* NOI18N */"java.awt.Font", null,
135		       DEFAULT | DONTFETCH);
136    }
137
138    protected Object getOnBody(String key) {
139        Component comp = (Component)body;
140
141        if (key.equals(/* NOI18N */"visible"))
142	    return (getFromTable(/* NOI18N */"visible"));
143        else if (key.equals(/* NOI18N */"enabled"))
144            return (new Boolean(comp.isEnabled()));
145        else if (key.equals(/* NOI18N */"foreground"))
146            return (comp.getForeground());
147        else if (key.equals(/* NOI18N */"background"))
148            return (comp.getBackground());
149        else if (key.equals(/* NOI18N */"font"))
150            return (comp.getFont());
151        else
152            return (super.getOnBody(key));
153    }
154
155    public void set(String key, Object value) {
156        if (key.equals(/* NOI18N */"visible")) {
157            boolean oldValue =
158		((Boolean)getFromTable(/* NOI18N */"visible")).booleanValue();
159            boolean newValue = ((Boolean)value).booleanValue();
160
161            if (newValue != oldValue) {
162                if (newValue) {
163                    if (!isCreated()) {
164                        doingShow = true;
165                        create();
166                        doingShow = false;
167                    }
168
169                    super.set(key, value);
170
171                    if (this instanceof ContainerShadow)
172                        ((ContainerShadow)this).showGroups();
173                } else {
174                    super.set(key, value);
175
176                    if (this instanceof ContainerShadow)
177                        ((ContainerShadow)this).hideGroups();
178                }
179
180                return;
181            }
182        }
183
184        super.set(key, value);
185    }
186
187    protected void setOnBody(String key, Object value) {
188        Component comp = (Component)body;
189
190        if (key.equals(/* NOI18N */"visible")) {
191            // Don't let visible be set to false if we are the main container
192            // and we are running inside vjava.
193            if (inDesignerRoot() && isMainContainer() &&
194		!((Boolean)value).booleanValue()) {
195		    /* JSTYLED */
196                throw new VJException(Global.getMsg("sunsoft.jws.visual.rt.awt.java.awt.ComponentShadow.IllegalSetVisible"));
197            }
198
199            // We don't need to use the doingShow() method, because
200            // the "visible" attribute has the DEFAULT flag set,
201            // therefore setOnBody will be called during creation for
202            // the "visible" attribute only if the "visible" attribute
203            // is false.
204            if (!doingShow)
205                showComponent(((Boolean) value).booleanValue());
206        } else if (key.equals(/* NOI18N */"enabled"))
207            comp.setEnabled(((Boolean) value).booleanValue());
208        else if (key.equals(/* NOI18N */"foreground")) {
209            comp.setForeground((Color) value);
210        } else if (key.equals(/* NOI18N */"background")) {
211            comp.setBackground((Color) value);
212        } else if (key.equals(/* NOI18N */"font"))
213            comp.setFont((Font) value);
214        else
215            super.setOnBody(key, value);
216    }
217
218    protected boolean isMainContainer() {
219        Root r = getRoot();
220        if (r == null)
221            return false;
222
223        AttributeManager mgr = r.getMainChild();
224        if (mgr instanceof WindowShadow) {
225            WindowShadow win = (WindowShadow)mgr;
226            if (win.isPanel())
227		mgr = win.getPanel();
228        }
229
230        return (mgr == this);
231    }
232
233    public void createBody() {};
234
235    /**
236     * Overrides destroyBody() in Shadow so that removeNotify() gets called on
237     * AWT components when there will be no more references to them.
238     */
239    protected void destroyBody() {
240        if (body != null) {
241            ((Component)body).removeNotify();
242            body = null;
243        }
244    }
245
246    /**
247     * Calls show or hide, depending on the value of cond.
248     */
249    public void show(boolean cond) {
250        if (cond)
251            show();
252        else
253            hide();
254    }
255
256    /**
257     * Sets the visible attribute to true.
258     */
259    public void show() {
260        set(/* NOI18N */"visible", Boolean.TRUE);
261    }
262
263    /**
264     * Sets the visible attribute to false.
265     */
266    public void hide() {
267        set(/* NOI18N */"visible", Boolean.FALSE);
268    }
269
270    /**
271     * Calls showComponent or hideComponent, depending on the value of cond.
272     */
273    public void showComponent(boolean cond) {
274        if (cond)
275            showComponent();
276        else
277            hideComponent();
278    }
279
280    /**
281     * Shows the component.  Calling showComponent does not affect the
282     * value of the visible attrbute.  You should use "show" instead of
283     * "showComponent".  The only reason this method exists is that
284     * Visual Java needs to use it in certain situations.
285     */
286    public void showComponent() {
287        // Call create if it hasn't already been called.
288        if (!isCreated()) {
289            doingShow = true;
290            create();
291            doingShow = false;
292        }
293
294        ((Component)body).show();
295        validateMain();
296    }
297
298    /**
299     * Hides the component.  Calling hideComponent does not affect the
300     * value of the visible attrbute.  You should use "hide" instead of
301     * "hideComponent".  The only reason this method exists is that
302     * Visual Java needs to use it in certain situations.
303     */
304    public void hideComponent() {
305        if (body != null)
306	    {
307		((Component)body).hide();
308		validateMain();
309	    }
310    }
311
312    /**
313     * Returns true if we are doing a create operation in the
314     * middle of a show operation.  Create likes to call show if the
315     * visible attribute is set to true, but create shouldn't call
316     * show if show caused create to be called if the first place.
317     */
318    protected boolean doingShow() {
319        if (doingShow) {
320            return true;
321        } else {
322            Group g = getGroup();
323            if (g != null)
324                return DesignerAccess.doingShow(g);
325            else
326                return false;
327        }
328    }
329
330    /**
331     * Call validate to lay out the component and its children if they
332     * are not valid.
333     */
334    public void validate() {
335        if (body != null)
336            ((Component)body).validate();
337    }
338
339    /**
340     * Call invalidate to force the component to not be valid, so that
341     * it will be layed out again when validate is called.
342     */
343    public void invalidate() {
344        if (body != null)
345            ((Component)body).invalidate();
346    }
347
348    /**
349     * Returns the result from calling isShowing on the body.
350     */
351    public boolean isShowing() {
352        if (body != null)
353            return ((Component)body).isShowing();
354        else
355            return false;
356    }
357
358    public void validateMain()
359    {
360        Root root = getRoot();
361        if (root == null)
362            return;
363        // Try the main container
364        AttributeManager mgr = root.getMainChild();
365        if (mgr instanceof Group)
366            mgr = DesignerAccess.getContainer((Group)mgr);
367
368        if (mgr instanceof ContainerShadow)
369	    {
370		ContainerShadow fs = ((ContainerShadow)mgr);
371		Container f = (Container)fs.getBody();
372		f.validate();
373	    }
374    }
375}
376