001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.form.layoutsupport.delegates;
043:
044: import java.awt.*;
045: import javax.swing.*;
046: import java.beans.*;
047: import java.util.Iterator;
048: import java.lang.reflect.Method;
049:
050: import org.openide.nodes.*;
051:
052: import org.netbeans.modules.form.layoutsupport.*;
053: import org.netbeans.modules.form.codestructure.*;
054: import org.netbeans.modules.form.FormProperty;
055:
056: /**
057: * Dedicated layout support class for JLayeredPane. It is based on
058: * AbsoluteLayoutSupport - similarly as NullLayoutSupport, but with one
059: * additional constraints parameter - the layer.
060: *
061: * @author Tomas Pavek
062: */
063:
064: public class JLayeredPaneSupport extends AbsoluteLayoutSupport {
065:
066: private static Method setBoundsMethod;
067:
068: /** Gets the supported layout manager class - JLayeredPane.
069: * @return the class supported by this delegate
070: */
071: @Override
072: public Class getSupportedClass() {
073: return JLayeredPane.class;
074: }
075:
076: /** This method is called when switching layout - giving an opportunity to
077: * convert the previous constrainst of components to constraints of the new
078: * layout (this layout). It should do nothing for JLayeredPane - but with
079: * must override it from from AbsoluteLayoutSupport.
080: * @param previousConstraints [input] layout constraints of components in
081: * the previous layout
082: * @param currentConstraints [output] array of converted constraints for
083: * the new layout - to be filled
084: * @param components [input] real components in a real container having the
085: * previous layout
086: */
087: @Override
088: public void convertConstraints(
089: LayoutConstraints[] previousConstraints,
090: LayoutConstraints[] currentConstraints,
091: Component[] components) {
092: return; // not needed here (contrary to AbsoluteLayoutSupport)
093: }
094:
095: /** Adds real components to given container (according to layout
096: * constraints stored for the components).
097: * @param container instance of a real container to be added to
098: * @param containerDelegate effective container delegate of the container
099: * @param components components to be added
100: * @param index position at which to add the components to container
101: */
102: @Override
103: public void addComponentsToContainer(Container container,
104: Container containerDelegate, Component[] components,
105: int index) {
106: if (!(container instanceof JLayeredPane))
107: return;
108:
109: for (int i = 0; i < components.length; i++) {
110: LayoutConstraints constraints = getConstraints(i + index);
111: if (constraints instanceof LayeredConstraints) {
112: Component comp = components[i];
113: container.add(comp, constraints.getConstraintsObject(),
114: i + index);
115:
116: Rectangle bounds = ((LayeredConstraints) constraints)
117: .getBounds();
118: if (bounds.width == -1 || bounds.height == -1) {
119: Dimension pref = comp.getPreferredSize();
120: if (bounds.width == -1)
121: bounds.width = pref.width;
122: if (bounds.height == -1)
123: bounds.height = pref.height;
124: }
125: comp.setBounds(bounds);
126: }
127: }
128: }
129:
130: // ------
131:
132: /** This method is called from readComponentCode method to read layout
133: * constraints of a component from code.
134: * @param constrExp CodeExpression object of the constraints (taken from
135: * add method in the code)
136: * @param constrCode CodeGroup to be filled with the relevant constraints
137: * initialization code
138: * @param compExp CodeExpression of the component for which the constraints
139: * are read
140: * @return LayoutConstraints based on information read form code
141: */
142: @Override
143: protected LayoutConstraints readConstraintsCode(
144: CodeExpression constrExp, CodeGroup constrCode,
145: CodeExpression compExp) {
146: LayeredConstraints constr = new LayeredConstraints(0, 0, 0, -1,
147: -1);
148: // constr.refComponent = getLayoutContext().getPrimaryComponent(index);
149:
150: Iterator it = CodeStructure
151: .getDefinedStatementsIterator(compExp);
152: CodeStatement[] statements = CodeStructure.filterStatements(it,
153: getSetBoundsMethod());
154: if (statements.length > 0) {
155: CodeStatement boundsStatement = statements[statements.length - 1];
156: constr.readPropertyExpressions(boundsStatement
157: .getStatementParameters(), 1);
158: constrCode.addStatement(boundsStatement);
159: }
160:
161: FormCodeSupport.readPropertyExpression(constrExp, constr
162: .getProperties()[0], false);
163:
164: return constr;
165: }
166:
167: /** Creates code for a component added to the layout (opposite to
168: * readComponentCode method).
169: * @param componentCode CodeGroup to be filled with complete component code
170: * (code for initializing the layout constraints and adding the
171: * component to the layout)
172: * @param compExp CodeExpression object representing component
173: * @param index position of the component in the layout
174: */
175: @Override
176: protected CodeExpression createConstraintsCode(
177: CodeGroup constrCode, LayoutConstraints constr,
178: CodeExpression compExp, int index) {
179: if (!(constr instanceof LayeredConstraints))
180: return null;
181:
182: LayeredConstraints layerConstr = (LayeredConstraints) constr;
183: layerConstr.refComponent = getLayoutContext()
184: .getPrimaryComponent(index);
185:
186: CodeStructure codeStructure = getCodeStructure();
187:
188: CodeStatement boundsStatement = CodeStructure.createStatement(
189: compExp, getSetBoundsMethod(), layerConstr
190: .createPropertyExpressions(codeStructure, 1));
191: constrCode.addStatement(boundsStatement);
192:
193: return codeStructure.createExpression(FormCodeSupport
194: .createOrigin(layerConstr.getProperties()[0]));
195: }
196:
197: /** This method is called to get a default component layout constraints
198: * metaobject in case it is not provided (e.g. in addComponents method).
199: * @return the default LayoutConstraints object for the supported layout;
200: * null if no component constraints are used
201: */
202: @Override
203: protected LayoutConstraints createDefaultConstraints() {
204: return new LayeredConstraints(0, 0, 0, -1, -1);
205: }
206:
207: // ----------
208:
209: // overriding AbsoluteLayoutSupport
210: @Override
211: protected LayoutConstraints createNewConstraints(
212: LayoutConstraints currentConstr, int x, int y, int w, int h) {
213: int layer = currentConstr instanceof LayeredConstraints ? ((LayeredConstraints) currentConstr)
214: .getLayer()
215: : 0;
216:
217: return new LayeredConstraints(layer, x, y, w, h);
218: }
219:
220: private static Method getSetBoundsMethod() {
221: if (setBoundsMethod == null) {
222: try {
223: setBoundsMethod = Component.class.getMethod(
224: "setBounds", // NOI18N
225: new Class[] { Integer.TYPE, Integer.TYPE,
226: Integer.TYPE, Integer.TYPE });
227: } catch (NoSuchMethodException ex) { // should not happen
228: ex.printStackTrace();
229: }
230: }
231: return setBoundsMethod;
232: }
233:
234: // ----------
235:
236: /** Extended AbsoluteLayoutConstraints class - with additional layer
237: * property.
238: */
239: public static class LayeredConstraints extends
240: AbsoluteLayoutConstraints {
241: private int layer;
242:
243: public LayeredConstraints(int layer, int x, int y, int w, int h) {
244: super (x, y, w, h);
245: this .layer = layer;
246: nullMode = true;
247: }
248:
249: public int getLayer() {
250: return layer;
251: }
252:
253: // ------
254:
255: @Override
256: public Object getConstraintsObject() {
257: return new Integer(layer);
258: }
259:
260: @Override
261: public LayoutConstraints cloneConstraints() {
262: return new LayeredConstraints(layer, x, y, w, h);
263: }
264:
265: // -------
266:
267: @Override
268: protected Node.Property[] createProperties() {
269: Node.Property[] props = super .createProperties();
270: Node.Property[] layeredProps = new Node.Property[props.length + 1];
271:
272: layeredProps[0] = new FormProperty(
273: "LayeredConstraints layer", // NOI18N
274: Integer.TYPE, getBundle().getString("PROP_layer"), // NOI18N
275: getBundle().getString("HINT_layer")) { // NOI18N
276:
277: public Object getTargetValue() {
278: return new Integer(layer);
279: }
280:
281: public void setTargetValue(Object value) {
282: layer = ((Integer) value).intValue();
283: }
284:
285: @Override
286: public boolean supportsDefaultValue() {
287: return true;
288: }
289:
290: @Override
291: public Object getDefaultValue() {
292: return new Integer(0);
293: }
294:
295: @Override
296: public PropertyEditor getExpliciteEditor() {
297: return new LayerEditor();
298: }
299:
300: @Override
301: public Object getValue(String key) {
302: if ("canEditAsText".equals(key)) // NOI18N
303: return Boolean.TRUE;
304: return super .getValue(key);
305: }
306:
307: @Override
308: public void setPropertyContext(
309: org.netbeans.modules.form.FormPropertyContext ctx) { // disabling this method due to limited persistence
310: } // capabilities (compatibility with previous versions)
311: };
312:
313: for (int i = 0; i < props.length; i++)
314: layeredProps[i + 1] = props[i];
315:
316: return layeredProps;
317: }
318: }
319:
320: // ---------
321:
322: public static final class LayerEditor extends PropertyEditorSupport {
323:
324: final String[] tags = { "DEFAULT_LAYER", // NOI18N
325: "PALETTE_LAYER", // NOI18N
326: "MODAL_LAYER", // NOI18N
327: "POPUP_LAYER", // NOI18N
328: "DRAG_LAYER" // NOI18N
329: };
330:
331: final Integer[] values = { JLayeredPane.DEFAULT_LAYER,
332: JLayeredPane.PALETTE_LAYER, JLayeredPane.MODAL_LAYER,
333: JLayeredPane.POPUP_LAYER, JLayeredPane.DRAG_LAYER };
334:
335: final String[] javaInitStrings = {
336: "javax.swing.JLayeredPane.DEFAULT_LAYER", // NOI18N
337: "javax.swing.JLayeredPane.PALETTE_LAYER", // NOI18N
338: "javax.swing.JLayeredPane.MODAL_LAYER", // NOI18N
339: "javax.swing.JLayeredPane.POPUP_LAYER", // NOI18N
340: "javax.swing.JLayeredPane.DRAG_LAYER" // NOI18N
341: };
342:
343: @Override
344: public String[] getTags() {
345: return tags;
346: }
347:
348: @Override
349: public String getAsText() {
350: Object value = getValue();
351: for (int i = 0; i < values.length; i++)
352: if (values[i].equals(value))
353: return tags[i];
354:
355: return value.toString();
356: }
357:
358: @Override
359: public void setAsText(String str) {
360: for (int i = 0; i < tags.length; i++)
361: if (tags[i].equals(str)) {
362: setValue(values[i]);
363: return;
364: }
365:
366: try {
367: setValue(new Integer(Integer.parseInt(str)));
368: } catch (NumberFormatException e) {
369: } // ignore
370: }
371:
372: @Override
373: public String getJavaInitializationString() {
374: Object value = getValue();
375: for (int i = 0; i < values.length; i++)
376: if (values[i].equals(value))
377: return javaInitStrings[i];
378:
379: return value != null ? "new Integer(" + value.toString()
380: + ")" // NOI18N
381: : null;
382: }
383: }
384: }
|