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-2007 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: package com.sun.jsfcl.std.property;
042:
043: import java.awt.Component;
044: import java.util.Iterator;
045: import java.util.List;
046: import com.sun.jsfcl.std.reference.CompositeReferenceData;
047: import com.sun.jsfcl.std.reference.ReferenceDataItem;
048: import com.sun.jsfcl.std.reference.ReferenceDataManager;
049: import org.openide.explorer.propertysheet.ExPropertyEditor;
050: import org.openide.explorer.propertysheet.PropertyEnv;
051:
052: /**
053: * I expect to find a value named referenceDataGetter in the property descriptor I get given.
054: * @author eric
055: *
056: * @deprecated
057: */
058: public class ChooseOneReferenceDataPropertyEditor extends
059: AbstractPropertyEditor implements ExPropertyEditor {
060: /**
061: * This String attribute defines the class to be used by the ReferenceDataPropertyEditor the
062: * property has defined as its propertyEditor. This will be used to determine the list of choices
063: * the property will present either via a drop down or customer panel on the property sheet.
064: */
065: public static final String REFERENCE_DATA_NAME = "referenceDataDefiner"; // NOI18N
066:
067: protected final static int MAX_CHOICE_COUNT_FOR_TAGS = 8;
068:
069: protected CompositeReferenceData compositeReferenceData;
070: protected long lastRefreshTime;
071: protected ReferenceDataItem valueReferenceDataItem;
072:
073: public ChooseOneReferenceDataPropertyEditor() {
074:
075: }
076:
077: public void attachToNewDesignProperty() {
078:
079: super .attachToNewDesignProperty();
080: compositeReferenceData = getCompositeReferenceDataImp();
081: setValue(getDesignProperty().getValue());
082: }
083:
084: /**
085: * Gets the property value as a string suitable for presentation
086: * to a human to edit.
087: *
088: * @return The property value as a string suitable for presentation
089: * to a human to edit.
090: * <p> Returns "null" is the value can't be expressed as a string.
091: * <p> If a non-null value is returned, then the PropertyEditor should
092: * be prepared to parse that string back in setAsText().
093: */
094: public String getAsText() {
095:
096: return getStringForItem(valueReferenceDataItem);
097: }
098:
099: public CompositeReferenceData getCompositeReferenceDataImp() {
100: String name = (String) getDesignProperty()
101: .getPropertyDescriptor().getValue(REFERENCE_DATA_NAME);
102: if (name == null) {
103: throw new RuntimeException("Property named: "
104: + getDesignProperty().getPropertyDescriptor()
105: .getDisplayName() + " has no "
106: + REFERENCE_DATA_NAME + "specified !!!"); // NOI18N
107: }
108: CompositeReferenceData result = ReferenceDataManager
109: .getInstance().getCompositeReferenceData(name,
110: getProject(), getDesignProperty());
111: if (result == null) {
112: throw new RuntimeException("Property named: "
113: + getDesignProperty().getPropertyDescriptor()
114: .getDisplayName()
115: + " got null for reference data named: " + name); // NOI18N
116: }
117: return result;
118: }
119:
120: /**
121: * A PropertyEditor may chose to make available a full custom Component
122: * that edits its property value. It is the responsibility of the
123: * PropertyEditor to hook itself up to its editor Component itself and
124: * to report property value changes by firing a PropertyChange event.
125: * <P>
126: * The higher-level code that calls getCustomEditor may either embed
127: * the Component in some larger property sheet, or it may put it in
128: * its own individual dialog, or ...
129: *
130: * @return A java.awt.Component that will allow a human to directly
131: * edit the current property value. May be null if this is
132: * not supported.
133: */
134: public Component getCustomEditor() {
135: return new ChooseOneReferenceDataPanel(this ,
136: getDesignProperty());
137: }
138:
139: public ReferenceDataItem getItemByName(String name) {
140:
141: if (name == null) {
142: return getItemByValue(null);
143: }
144: name = name.trim();
145: for (Iterator iterator = getItems().iterator(); iterator
146: .hasNext();) {
147: ReferenceDataItem item = (ReferenceDataItem) iterator
148: .next();
149: if (name.equals(item.getName())) {
150: return item;
151: }
152: }
153: if (getCompositeReferenceData().canAddRemoveItems()) {
154: ReferenceDataItem item = getCompositeReferenceData()
155: .getDefiner().newItem(name, name, false, true);
156: getCompositeReferenceData().add(item);
157: return item;
158: }
159: return null;
160: }
161:
162: public ReferenceDataItem getItemByValue(Object value) {
163:
164: for (Iterator iterator = getItems().iterator(); iterator
165: .hasNext();) {
166: ReferenceDataItem item = (ReferenceDataItem) iterator
167: .next();
168: if (value == null) {
169: if (item.getValue() == null) {
170: return item;
171: }
172: } else {
173: if (value.equals(item.getValue())) {
174: return item;
175: }
176: }
177: }
178: return null;
179: }
180:
181: public List getItems() {
182:
183: return getCompositeReferenceData().getItemsSorted();
184: }
185:
186: public CompositeReferenceData getCompositeReferenceData() {
187:
188: return compositeReferenceData;
189: }
190:
191: public String getJavaInitializationString() {
192:
193: if (valueReferenceDataItem == null
194: || valueReferenceDataItem.isUnsetMarker()) {
195: return null;
196: }
197: if (valueReferenceDataItem.getJavaInitializationString() != null) {
198: return valueReferenceDataItem.getJavaInitializationString();
199: }
200: if (valueReferenceDataItem.getValue() == null) {
201: return null;
202: }
203: if (valueReferenceDataItem.getValue() instanceof String) {
204: return stringToJavaSourceString((String) valueReferenceDataItem
205: .getValue());
206: }
207: throw new RuntimeException("Badly setup reference data item: "
208: + getCompositeReferenceData().getName() + ":"
209: + valueReferenceDataItem.getName());
210: }
211:
212: protected String getStringForItem(ReferenceDataItem item) {
213:
214: if (item == null) {
215: return ""; // NOI18N
216: }
217: String string;
218: if (getCompositeReferenceData().isValueAString()) {
219: string = (String) item.getValue();
220: } else {
221: string = item.getName();
222: }
223: if (string == null) {
224: string = ""; // NOI18N
225: }
226: return string;
227: }
228:
229: public String[] getTags() {
230:
231: if (getCompositeReferenceData().canAddRemoveItems()) {
232: return null;
233: }
234: List items = getItems();
235: if (items.size() > MAX_CHOICE_COUNT_FOR_TAGS) {
236: return null;
237: }
238:
239: String[] result = new String[items.size()];
240: int i = 0;
241: for (Iterator iterator = items.iterator(); iterator.hasNext(); i++) {
242: result[i] = ((ReferenceDataItem) iterator.next()).getName();
243: }
244: return result;
245: }
246:
247: public ReferenceDataItem getValueReferenceDataItem() {
248:
249: return valueReferenceDataItem;
250: }
251:
252: public boolean isPaintable() {
253:
254: // EATTODO: This CHEEZY as all get out, but its the only call I'm pretty sure is
255: // called first, before the others, and not as often as getTags in one pass when
256: // there is need of tags :( I used to have it on getTags, but that gets called too
257: // many times, plus the fact that getTags turns around and immediately causes
258: // items to be rebuild again.
259: // MUST FIND a better way to do this
260: if (System.currentTimeMillis() - lastRefreshTime > 10000) {
261: refreshItems();
262: lastRefreshTime = System.currentTimeMillis();
263: }
264: return super .isPaintable();
265: }
266:
267: public void refreshItems() {
268:
269: getCompositeReferenceData()
270: .invalidateDesignContextRelatedCaches();
271: }
272:
273: /**
274: * Sets the property value by parsing a given String. May raise
275: * java.lang.IllegalArgumentException if either the String is
276: * badly formatted or if this kind of property can't be expressed
277: * as text.
278: *
279: * @param text The string to be parsed.
280: */
281: public void setAsText(String text)
282: throws java.lang.IllegalArgumentException {
283:
284: valueReferenceDataItem = getItemByName(text);
285: if (valueReferenceDataItem == null) {
286: super .setValue(null);
287: throw new LocalizedMessageRuntimeException(
288: "Unknown value: \"" + text + "\"");
289: }
290: super .setValue(valueReferenceDataItem.getValue());
291: }
292:
293: public void setValue(Object object) {
294:
295: setValueImp(object);
296: super .setValue(object);
297: }
298:
299: public void setValueImp(Object object) {
300:
301: valueReferenceDataItem = getItemByValue(object);
302: }
303:
304: /**
305: * Determines whether the propertyEditor can provide a custom editor.
306: *
307: * @return True if the propertyEditor can provide a custom editor.
308: */
309: public boolean supportsCustomEditor() {
310:
311: if (getCompositeReferenceData().canAddRemoveItems()) {
312: return true;
313: }
314: return getItems().size() > MAX_CHOICE_COUNT_FOR_TAGS;
315: }
316:
317: private PropertyEnv propertyEnv;
318:
319: public void attachEnv(PropertyEnv propertyEnv) {
320: this .propertyEnv = propertyEnv;
321: }
322:
323: public PropertyEnv getEnv() {
324: return this.propertyEnv;
325: }
326:
327: }
|