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;
043:
044: import java.beans.*;
045: import java.util.*;
046: import org.openide.explorer.propertysheet.editors.XMLPropertyEditor;
047: import org.openide.util.NbBundle;
048:
049: /**
050: * Property editor allowing to choose a component from all components in form
051: * (FormModel). Choice can be restricted to certain bean types.
052: *
053: * @author Tomas Pavek
054: */
055:
056: public class ComponentChooserEditor implements PropertyEditor,
057: FormAwareEditor, XMLPropertyEditor, NamedPropertyEditor {
058: public static final int ALL_COMPONENTS = 0;
059: public static final int NONVISUAL_COMPONENTS = 3;
060: // public static final int VISUAL_COMPONENTS = 1;
061: // public static final int OTHER_COMPONENTS = 2;
062:
063: private static final String NULL_REF = "null"; // NOI18N
064: private static final String INVALID_REF = "default"; // NOI18N
065:
066: private static String noneText = null;
067: private static String invalidText = null;
068: private static String defaultText = null;
069:
070: private FormModel formModel;
071: private List<RADComponent> components;
072: private Class[] beanTypes = null;
073: private int componentCategory = 0;
074:
075: private Object defaultValue;
076: private ComponentRef value;
077:
078: private PropertyChangeSupport changeSupport;
079:
080: public ComponentChooserEditor() {
081: }
082:
083: public ComponentChooserEditor(Class[] componentTypes) {
084: beanTypes = componentTypes;
085: }
086:
087: // --------------
088: // PropertyEditor implementation
089:
090: public void setValue(Object value) {
091: defaultValue = null;
092: if (value == null || value instanceof ComponentRef)
093: this .value = (ComponentRef) value;
094:
095: else if (value instanceof RADComponent)
096: this .value = new ComponentRef((RADComponent) value);
097: else if (value instanceof String)
098: this .value = new ComponentRef((String) value);
099: else {
100: this .value = null;
101: defaultValue = value;
102: }
103:
104: //return;
105:
106: firePropertyChange();
107: }
108:
109: public Object getValue() {
110: if (value != null && INVALID_REF.equals(value.getDescription()))
111: return BeanSupport.NO_VALUE; // special - invalid value was loaded
112:
113: return isDefaultValue() ? defaultValue : value;
114: }
115:
116: public String[] getTags() {
117: List compList = getComponents();
118:
119: int extraValues = 0;
120: int count = 0;
121: String[] names;
122:
123: if (isDefaultValue()) {
124: extraValues = 2;
125: count = compList.size() + extraValues;
126: names = new String[count];
127: names[0] = defaultString();
128: } else {
129: extraValues = 1;
130: count = compList.size() + extraValues;
131: names = new String[count];
132: }
133: names[extraValues - 1] = noneString();
134:
135: if (count > extraValues) {
136: for (int i = extraValues; i < count; i++)
137: names[i] = ((RADComponent) compList
138: .get(i - extraValues)).getName();
139: Arrays.sort(names, 1, count);
140: }
141:
142: return names;
143: }
144:
145: private boolean isDefaultValue() {
146: return value == null && defaultValue != null;
147: }
148:
149: public String getAsText() {
150: if (isDefaultValue())
151: return defaultString();
152: if (value == null)
153: return noneString();
154: if (value.getComponent() == null)
155: return invalidString();
156:
157: String str = value.getDescription();
158: return NULL_REF.equals(str) ? noneString() : str;
159: }
160:
161: public void setAsText(String str) {
162: if (str == null || str.equals("") || str.equals(noneString())) // NOI18N
163: setValue(null);
164: else {
165: if (defaultString().equals(str)) {
166: // XXX
167: setValue(defaultValue);
168: } else {
169: setValue(str);
170: }
171:
172: }
173:
174: }
175:
176: public String getJavaInitializationString() {
177: return value != null ? value.getJavaInitString() : null;
178: }
179:
180: public void addPropertyChangeListener(PropertyChangeListener l) {
181: synchronized (this ) {
182: if (changeSupport == null)
183: changeSupport = new PropertyChangeSupport(this );
184: }
185: changeSupport.addPropertyChangeListener(l);
186: }
187:
188: public void removePropertyChangeListener(PropertyChangeListener l) {
189: if (changeSupport != null)
190: changeSupport.removePropertyChangeListener(l);
191: }
192:
193: public boolean isPaintable() {
194: return false;
195: }
196:
197: public void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box) {
198: }
199:
200: public java.awt.Component getCustomEditor() {
201: return null;
202: }
203:
204: public boolean supportsCustomEditor() {
205: return false;
206: }
207:
208: // ----------------
209:
210: // FormAwareEditor implementation
211: public void setContext(FormModel model, FormProperty prop) {
212: formModel = model;
213: }
214:
215: // FormAwareEditor implementation
216: public void updateFormVersionLevel() {
217: }
218:
219: public FormModel getFormModel() {
220: return formModel;
221: }
222:
223: public void setBeanTypes(Class[] types) {
224: beanTypes = types;
225: }
226:
227: public Class[] getBeanTypes() {
228: return beanTypes;
229: }
230:
231: public void setComponentCategory(int cat) {
232: componentCategory = cat;
233: }
234:
235: public int getComponentCategory() {
236: return componentCategory;
237: }
238:
239: // ----------------
240: // XMLPropertyEditor implementation
241:
242: private static final String XML_COMPONENT = "ComponentRef"; // NOI18N
243: private static final String ATTR_NAME = "name"; // NOI18N
244:
245: public org.w3c.dom.Node storeToXML(org.w3c.dom.Document doc) {
246: String nameStr;
247: if (value != null)
248: nameStr = value.getComponent() != null ? value
249: .getDescription() : INVALID_REF;
250: else
251: nameStr = NULL_REF;
252:
253: org.w3c.dom.Element el = doc.createElement(XML_COMPONENT);
254: el.setAttribute(ATTR_NAME, nameStr);
255: return el;
256: }
257:
258: public void readFromXML(org.w3c.dom.Node element)
259: throws java.io.IOException {
260: if (!XML_COMPONENT.equals(element.getNodeName()))
261: throw new java.io.IOException();
262:
263: org.w3c.dom.NamedNodeMap attributes;
264: org.w3c.dom.Node nameAttr;
265: String name;
266:
267: if ((attributes = element.getAttributes()) != null
268: && (nameAttr = attributes.getNamedItem(ATTR_NAME)) != null
269: && (name = nameAttr.getNodeValue()) != null) {
270: if (NULL_REF.equals(name)) {
271: value = null;
272: } else {
273: value = new ComponentRef(name);
274: }
275: }
276: }
277:
278: // ---------
279:
280: protected List getComponents() {
281: if (components == null)
282: components = new ArrayList<RADComponent>();
283: else
284: components.clear();
285:
286: if (formModel != null) {
287: Collection<RADComponent> comps;
288: if (componentCategory == NONVISUAL_COMPONENTS)
289: comps = formModel.getNonVisualComponents();
290: else
291: comps = formModel.getAllComponents();
292:
293: for (RADComponent metacomp : comps)
294: if (acceptBean(metacomp))
295: components.add(metacomp);
296: }
297:
298: return components;
299: }
300:
301: protected boolean acceptBean(RADComponent comp) {
302: if (beanTypes == null)
303: return true;
304:
305: boolean match = false;
306: for (int i = 0; i < beanTypes.length && !match; i++)
307: match = beanTypes[i].isAssignableFrom(comp.getBeanClass());
308:
309: return match;
310: }
311:
312: protected String noneString() {
313: if (noneText == null)
314: noneText = FormUtils.getBundleString("CTL_NoComponent"); // NOI18N
315: return noneText;
316: }
317:
318: protected String defaultString() {
319: if (defaultText == null)
320: defaultText = FormUtils
321: .getBundleString("CTL_DefaultComponent"); // NOI18N
322: return defaultText;
323: }
324:
325: protected String invalidString() {
326: if (invalidText == null)
327: invalidText = FormUtils
328: .getBundleString("CTL_InvalidReference"); // NOI18N
329: return invalidText;
330: }
331:
332: // ------
333:
334: protected final void firePropertyChange() {
335: if (changeSupport != null)
336: changeSupport.firePropertyChange(null, null, null);
337: }
338:
339: // NamedPropertyEditor implementation
340: public String getDisplayName() {
341: return NbBundle.getBundle(getClass()).getString(
342: "CTL_ComponentChooserEditor_DisplayName"); // NOI18N
343: }
344:
345: // ------------
346:
347: private class ComponentRef extends FormDesignValueAdapter implements
348: RADComponent.ComponentReference {
349: private String componentName;
350: private RADComponent component;
351:
352: ComponentRef(String name) {
353: componentName = name;
354: }
355:
356: ComponentRef(RADComponent metacomp) {
357: componentName = metacomp.getName();
358: component = metacomp;
359: }
360:
361: @Override
362: public boolean equals(Object obj) {
363: boolean equal;
364:
365: if (obj instanceof ComponentRef) {
366: ComponentRef ref = (ComponentRef) obj;
367:
368: equal = (ref.component == component);
369: if (componentName == null) {
370: equal = equal && (ref.componentName == null);
371: } else {
372: equal = equal
373: && componentName.equals(ref.componentName);
374: }
375: } else {
376: equal = (obj instanceof RADComponent && obj == component);
377: }
378:
379: return equal;
380: }
381:
382: @Override
383: public int hashCode() {
384: int hash = 5;
385: hash = 89
386: * hash
387: + (this .componentName != null ? this .componentName
388: .hashCode() : 0);
389: hash = 89
390: * hash
391: + (this .component != null ? this .component
392: .hashCode() : 0);
393: return hash;
394: }
395:
396: String getJavaInitString() {
397: checkComponent();
398:
399: if (component != null) {
400: if (component == component.getFormModel()
401: .getTopRADComponent())
402: return "this"; // NOI18N
403: } else if (!NULL_REF.equals(componentName))
404: return null; // invalid reference
405:
406: return componentName;
407: }
408:
409: public RADComponent getComponent() {
410: checkComponent();
411: return component;
412: }
413:
414: /** FormDesignValue implementation. */
415: @Override
416: public String getDescription() {
417: checkComponent();
418: return componentName;
419: }
420:
421: /** FormDesignValue implementation. */
422: public Object getDesignValue() {
423: checkComponent();
424: return component != null ? component.getBeanInstance()
425: : IGNORED_VALUE;
426: }
427:
428: private void checkComponent() {
429: if (component == null && !NULL_REF.equals(componentName)
430: && !INVALID_REF.equals(componentName)) {
431: List compList = getComponents();
432: Iterator it = compList.iterator();
433: while (it.hasNext()) {
434: RADComponent comp = (RADComponent) it.next();
435: if (comp.getName().equals(componentName)) {
436: if (comp.isInModel())
437: component = comp;
438: break;
439: }
440: }
441: } else if (component != null) {
442: if (!component.isInModel())
443: component = null;
444: else
445: componentName = component.getName();
446: }
447: }
448: }
449: }
|