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.beaninfo.editors;
043:
044: import java.beans.*;
045: import java.text.MessageFormat;
046: import java.util.*;
047: import org.netbeans.core.UIExceptions;
048: import org.openide.explorer.propertysheet.ExPropertyEditor;
049: import org.openide.explorer.propertysheet.PropertyEnv;
050:
051: import org.openide.loaders.ExtensionList;
052: import org.openide.util.NbBundle;
053: import org.openide.nodes.Node;
054:
055: /** Property editor for {@link ExtensionList}s.
056: *
057: * @see ExtensionList
058: *
059: * @author Jaroslav Tulach
060: * @version 0.11 November 11, 1997
061: */
062: public class ExtensionListEditor extends Object implements
063: PropertyEditor, ExPropertyEditor {
064: /** value to edit */
065: private ExtensionList value;
066: private PropertyChangeSupport support = new PropertyChangeSupport(
067: this );
068:
069: private boolean editable = true;
070:
071: /*
072: * Set (or change) the object that is to be edited. Builtin types such
073: * as "int" must be wrapped as the corresponding object type such as
074: * "java.lang.Integer".
075: *
076: * @param value The new target object to be edited. Note that this
077: * object should not be modified by the PropertyEditor, rather
078: * the PropertyEditor should create a new object to hold any
079: * modified value.
080: */
081: public void setValue(Object value) {
082: if (value != null)
083: this .value = (ExtensionList) ((ExtensionList) value)
084: .clone();
085: else
086: this .value = null;
087: support.firePropertyChange(null, null, null);
088: }
089:
090: /*
091: * @return The value of the property. Builtin types such as "int" will
092: * be wrapped as the corresponding object type such as "java.lang.Integer".
093: */
094: public Object getValue() {
095: return value;
096: }
097:
098: /*
099: * @return True if the class will honor the paintValue method.
100: */
101: public boolean isPaintable() {
102: return false;
103: }
104:
105: /*
106: * Paint a representation of the value into a given area of screen
107: * real estate. Note that the propertyEditor is responsible for doing
108: * its own clipping so that it fits into the given rectangle.
109: *
110:
111: * If the PropertyEditor doesn't honor paint requests (see isPaintable)
112: * this method should be a silent noop.
113: *
114:
115: * The given Graphics object will have the default font, color, etc of
116: * the parent container. The PropertyEditor may change graphics attributes
117: * such as font and color and doesn't need to restore the old values.
118: *
119: * @param gfx Graphics object to paint into.
120: * @param box Rectangle within graphics object into which we should paint.
121: */
122: public void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box) {
123: }
124:
125: /*
126: * This method is intended for use when generating Java code to set
127: * the value of the property. It should return a fragment of Java code
128: * that can be used to initialize a variable with the current property
129: * value.
130: *
131:
132: * Example results are "2", "new Color(127,127,34)", "Color.orange", etc.
133: *
134: * @return A fragment of Java code representing an initializer for the
135: * current value.
136: */
137: public String getJavaInitializationString() {
138: return null;
139: }
140:
141: /*
142: * @return The property value as a human editable string.
143: * Returns null if the value can't be expressed as an editable string.
144: * If a non-null value is returned, then the PropertyEditor should
145: * be prepared to parse that string back in setAsText().
146: */
147: public String getAsText() {
148: StringBuffer sb = new StringBuffer();
149: String[] exts = getStringArray();
150: for (int i = 0; i < exts.length; i++) {
151: if (i > 0)
152: sb.append(", "); // NOI18N
153: sb.append(exts[i]);
154: }
155: return sb.toString();
156: }
157:
158: /*
159: * Set the property value by parsing a given String. May raise
160: * java.lang.IllegalArgumentException if either the String is
161: * badly formatted or if this kind of property can't be expressed
162: * as text.
163: * @param text The string to be parsed.
164: */
165: public void setAsText(String text)
166: throws java.lang.IllegalArgumentException {
167: try {
168: if (NbBundle
169: .getMessage(
170: org.openide.explorer.propertysheet.PropertyPanel.class,
171: "CTL_Different_Values").equals(text)) {
172: // XXX huh?!
173: setValue(new String[] { text });
174: } else {
175: StringTokenizer st = new StringTokenizer(text,
176: ",. \n\t"); // NOI18N
177: setAs(st);
178: }
179: } catch (Exception e) {
180: IllegalArgumentException iae = new IllegalArgumentException(
181: e.getMessage());
182: String msg = e.getLocalizedMessage();
183: if (msg == null) {
184: msg = MessageFormat.format(NbBundle.getMessage(
185: ExtensionListEditor.class,
186: "FMT_EXC_GENERIC_BAD_VALUE"), //NOI18N
187: new Object[] { text });
188: }
189: UIExceptions.annotateUser(iae, iae.getMessage(), msg, e,
190: new Date());
191: throw iae;
192: }
193: }
194:
195: /*
196: * If the property value must be one of a set of known tagged values,
197: * then this method should return an array of the tags. This can
198: * be used to represent (for example) enum values. If a PropertyEditor
199: * supports tags, then it should support the use of setAsText with
200: * a tag value as a way of setting the value and the use of getAsText
201: * to identify the current value.
202: *
203: * @return The tag values for this property. May be null if this
204: * property cannot be represented as a tagged value.
205: *
206: */
207: public String[] getTags() {
208: return null;
209: }
210:
211: /*
212: * A PropertyEditor may choose to make available a full custom Component
213: * that edits its property value. It is the responsibility of the
214: * PropertyEditor to hook itself up to its editor Component itself and
215: * to report property value changes by firing a PropertyChange event.
216: *
217:
218: * The higher-level code that calls getCustomEditor may either embed
219: * the Component in some larger property sheet, or it may put it in
220: * its own individual dialog, or ...
221: *
222: * @return A java.awt.Component that will allow a human to directly
223: * edit the current property value. May be null if this is
224: * not supported.
225: */
226:
227: public java.awt.Component getCustomEditor() {
228: return new ExtensionListCustomEditor(this );
229: }
230:
231: /*
232: * @return True if the propertyEditor can provide a custom editor.
233: */
234: public boolean supportsCustomEditor() {
235: return true;
236: }
237:
238: /*
239: * Register a listener for the PropertyChange event. When a
240: * PropertyEditor changes its value it should fire a PropertyChange
241: * event on all registered PropertyChangeListeners, specifying the
242: * null value for the property name and itself as the source.
243: *
244: * @param listener An object to be invoked when a PropertyChange
245: * event is fired.
246: */
247: public void addPropertyChangeListener(
248: PropertyChangeListener listener) {
249: support.addPropertyChangeListener(listener);
250: }
251:
252: /*
253: * Remove a listener for the PropertyChange event.
254: *
255: * @param listener The PropertyChange listener to be removed.
256: */
257: public void removePropertyChangeListener(
258: PropertyChangeListener listener) {
259: support.removePropertyChangeListener(listener);
260: }
261:
262: /** Used to acquire the current value from the PropertyEditor
263: * @return the current value of the property
264: */
265: @SuppressWarnings("unchecked")
266: public String[] getStringArray() {
267: if (value == null) {
268: return new String[0];
269: }
270: List<String> l = new ArrayList<String>();
271: Enumeration<String> e = (Enumeration<String>) value
272: .extensions();
273: while (e.hasMoreElements())
274: l.add(e.nextElement());
275:
276: e = (Enumeration<String>) value.mimeTypes();
277: while (e.hasMoreElements())
278: l.add(e.nextElement());
279:
280: Collections.sort(l);
281: return l.toArray(new String[l.size()]);
282: }
283:
284: /** Used to modify the current value in the PropertyEditor
285: * @param value the new value of the property
286: */
287: public void setStringArray(String[] nue) {
288: setAs(org.openide.util.Enumerations.array(nue));
289: }
290:
291: /** Sets the value as enumeration.
292: * @param en enumeration of strings
293: */
294: private void setAs(Enumeration en) {
295: ExtensionList list = new ExtensionList();
296:
297: while (en.hasMoreElements()) {
298: String tok = (String) en.nextElement();
299: if (tok.indexOf('/') >= 0) {
300: // mime type!?
301: list.addMimeType(tok);
302: } else {
303: list.addExtension(tok);
304: }
305: }
306: value = list;
307:
308: support.firePropertyChange(null, null, null);
309: }
310:
311: /** gets information if the text in editor should be editable or not */
312: public boolean isEditable() {
313: return (editable);
314: }
315:
316: public void attachEnv(PropertyEnv env) {
317: FeatureDescriptor desc = env.getFeatureDescriptor();
318: if (desc instanceof Node.Property) {
319: Node.Property prop = (Node.Property) desc;
320: editable = prop.canWrite();
321: }
322: }
323: }
|