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:
046: import org.openide.loaders.DataObject;
047: import org.openide.nodes.Node;
048: import org.openide.nodes.NodeAcceptor;
049: import org.openide.loaders.DataFolder;
050: import org.openide.loaders.DataFilter;
051: import org.openide.explorer.propertysheet.*;
052:
053: /**
054: * Property editor for org.openide.loaders.DataObject.
055: * Uses class DataObjectPanel as custom property editor.
056: * @author David Strupl
057: */
058: public class DataObjectEditor extends PropertyEditorSupport implements
059: ExPropertyEditor {
060:
061: /** Name of the custom property that can be passed in PropertyEnv. */
062: private static final String PROPERTY_CURRENT_FOLDER = "currentFolder"; // NOI18N
063: /** Name of the custom property that can be passed in PropertyEnv. */
064: private static final String PROPERTY_ROOT_FOLDER = "rootFolder"; // NOI18N
065: /** Name of the custom property that can be passed in PropertyEnv. */
066: private static final String PROPERTY_ROOT_NODE = "rootNode"; // NOI18N
067: /** Name of the custom property that can be passed in PropertyEnv. */
068: private static final String PROPERTY_COOKIES = "cookies"; // NOI18N
069: /** Name of the custom property that can be passed in PropertyEnv. */
070: private static final String PROPERTY_DATA_FILTER = "dataFilter"; // NOI18N
071: /** Name of the custom property that can be passed in PropertyEnv. */
072: private static final String PROPERTY_FOLDER_FILTER = "folderFilter"; // NOI18N
073: /** Name of the custom property that can be passed in PropertyEnv. */
074: private static final String PROPERTY_NODE_ACCEPTOR = "nodeAcceptor"; // NOI18N
075: /** Name of the custom property that can be passed in PropertyEnv. */
076: private static final String PROPERTY_LABEL = "label"; // NOI18N
077: /** Name of the custom property that can be passed in PropertyEnv. */
078: private static final String PROPERTY_TITLE = "title"; // NOI18N
079: /** Name of the custom property that can be passed in PropertyEnv. */
080: private static final String PROPERTY_INSET = "inset"; // NOI18N
081: /** Name of the custom property that can be passed in PropertyEnv. */
082: private static final String PROPERTY_DESCRIPTION = "description"; // NOI18N
083: /** Name of the custom property that can be passed in PropertyEnv. */
084: private static final String PROPERTY_GUI_TYPE = "guitype"; // NOI18N
085: /** Name of the custom property that can be passed in PropertyEnv. */
086: private static final String PROPERTY_SELECTION_MODE = "selectionMode"; // NOI18N
087:
088: /** This gets lazy initialized in getDataObjectPanel*/
089: private DataObjectPanel customEditor;
090:
091: /** A property stored between calls to atachEnv and getCustomEditor() */
092: private DataFolder rootFolder;
093: /** A property stored between calls to atachEnv and getCustomEditor() */
094: private Node rootNode;
095: /** A property stored between calls to atachEnv and getCustomEditor() */
096: private DataObject currentFolder;
097: /** A property stored between calls to atachEnv and getCustomEditor() */
098: private Class[] cookies;
099: /** A property stored between calls to atachEnv and getCustomEditor() */
100: private DataFilter dataFilter;
101: /** A property stored between calls to atachEnv and getCustomEditor() */
102: private DataFilter folderFilter;
103: /** A property stored between calls to atachEnv and getCustomEditor() */
104: private NodeAcceptor nodeAcceptor;
105: /** A property stored between calls to atachEnv and getCustomEditor() */
106: private String label;
107: /** A property stored between calls to atachEnv and getCustomEditor() */
108: private String title;
109: /** A property stored between calls to atachEnv and getCustomEditor() */
110: private Integer insets;
111: /** A property stored between calls to atachEnv and getCustomEditor() */
112: private String description;
113: /** A property stored between calls to atachEnv and getCustomEditor()
114: * It can be 'TreeView' or 'ListView'. Default is 'ListView'.
115: */
116: private String guiType;
117: /** A property stored between calls to atachEnv and getCustomEditor()
118: * Valid only for 'ListView' GUI type. It controls selection mode of
119: * JFileChooser.
120: *
121: * Valid values are:
122: * JFileChooser.FILES_ONLY
123: * JFileChooser.DIRECTORIES_ONLY
124: * JFileChooser.FILES_AND_DIRECTORIES
125: */
126: private Integer selectionMode;
127:
128: private PropertyChangeSupport supp = new PropertyChangeSupport(this );
129:
130: private PropertyEnv env;
131:
132: /**
133: * This method is called by the IDE to pass
134: * the environment to the property editor.
135: */
136: public void attachEnv(PropertyEnv env) {
137: Object newObj = env.getFeatureDescriptor().getValue(
138: PROPERTY_CURRENT_FOLDER);
139: if (newObj instanceof DataObject) {
140: currentFolder = (DataObject) newObj;
141: }
142: newObj = env.getFeatureDescriptor().getValue(
143: PROPERTY_ROOT_FOLDER);
144: if (newObj instanceof DataFolder) {
145: rootFolder = (DataFolder) newObj;
146: }
147: newObj = env.getFeatureDescriptor()
148: .getValue(PROPERTY_ROOT_NODE);
149: if (newObj instanceof Node) {
150: rootNode = (Node) newObj;
151: }
152: newObj = env.getFeatureDescriptor().getValue(PROPERTY_COOKIES);
153: if (newObj instanceof Class[]) {
154: cookies = (Class[]) newObj;
155: }
156: newObj = env.getFeatureDescriptor().getValue(
157: PROPERTY_DATA_FILTER);
158: if (newObj instanceof DataFilter) {
159: dataFilter = (DataFilter) newObj;
160: }
161: newObj = env.getFeatureDescriptor().getValue(
162: PROPERTY_FOLDER_FILTER);
163: if (newObj instanceof DataFilter) {
164: folderFilter = (DataFilter) newObj;
165: }
166: newObj = env.getFeatureDescriptor().getValue(
167: PROPERTY_NODE_ACCEPTOR);
168: if (newObj instanceof NodeAcceptor) {
169: nodeAcceptor = (NodeAcceptor) newObj;
170: }
171: newObj = env.getFeatureDescriptor().getValue(PROPERTY_LABEL);
172: if (newObj instanceof String) {
173: label = (String) newObj;
174: }
175: newObj = env.getFeatureDescriptor().getValue(PROPERTY_TITLE);
176: if (newObj instanceof String) {
177: title = (String) newObj;
178: }
179: newObj = env.getFeatureDescriptor().getValue(PROPERTY_INSET);
180: if (newObj instanceof Integer) {
181: insets = (Integer) newObj;
182: }
183: newObj = env.getFeatureDescriptor().getValue(
184: PROPERTY_DESCRIPTION);
185: if (newObj instanceof String) {
186: description = (String) newObj;
187: }
188: newObj = env.getFeatureDescriptor().getValue(PROPERTY_GUI_TYPE);
189: if (newObj instanceof String) {
190: guiType = (String) newObj;
191: }
192: newObj = env.getFeatureDescriptor().getValue(
193: PROPERTY_SELECTION_MODE);
194: if (newObj instanceof Integer) {
195: selectionMode = (Integer) newObj;
196: }
197: // fix of 19318, set canEditAsText to false by default
198: if (env.getFeatureDescriptor().getValue("canEditAsText") == null) { // NOI18N
199: env.getFeatureDescriptor().setValue("canEditAsText",
200: Boolean.FALSE); // NOI18N
201: }
202: if (env.getClass().equals(PropertyEnv.class)) {
203: if ((customEditor != null && customEditor.isVisible())
204: || customEditor == null) {
205: //allow reuse of the custom editor - it is probably being
206: //redisplayed, so we need to change the PropertyEnv that
207: //may be controlling the dialog.
208: this .env = env;
209: }
210: }
211: }
212:
213: /**
214: * Calls lazy initialization in getDataObjectpanel().
215: * @return an instanceof DataObjectPanel
216: */
217: public java.awt.Component getCustomEditor() {
218: return getDataObjectPanel();
219: }
220:
221: /**
222: * Lazy initializes customEditor (DataObjectPanel).
223: * Passes all parameters gathered in method attachEnv.
224: */
225: private DataObjectPanel getDataObjectPanel() {
226: //XXX we must cache the custom editor because the PropertyPanel usage
227: //will actually re-fetch it if something calls setState() on the env.
228: //The alternative is an endless loop during PropertyPanel initialization,
229: //as the initial OK button state is set, causing the PropertyPanel to
230: //rebuild itself, causing the OK button to be set again...
231: if (customEditor == null) {
232: if (guiType != null) {
233: if ("TreeView".equals(guiType)) {
234: customEditor = new DataObjectTreeView(this , env);
235: } else if ("ListView".equals(guiType)) {
236: customEditor = new DataObjectListView(this , env);
237: } else {
238: customEditor = new DataObjectListView(this , env);
239: }
240: } else {
241: customEditor = new DataObjectListView(this , env);
242: }
243: } else {
244: //Check explicitly for the env class - issue 36100
245: //env is changed before dialog invocation
246: customEditor.setEnv(env);
247: }
248: if (cookies != null) {
249: customEditor.setDataFilter(new CookieFilter(cookies,
250: dataFilter));
251: } else {
252: customEditor.setDataFilter(dataFilter);
253: }
254: Object value = getValue();
255: if (value != null && value instanceof DataObject) {
256: customEditor.setDataObject((DataObject) value);
257: } else if (currentFolder != null) {
258: customEditor.setDataObject(currentFolder);
259: }
260: if (label != null) {
261: customEditor.setText(label);
262: }
263: if (title != null) {
264: customEditor.putClientProperty("title", title); // NOI18N
265: }
266: if (nodeAcceptor != null) {
267: customEditor.setNodeFilter(nodeAcceptor);
268: }
269: if (folderFilter != null) {
270: customEditor.setFolderFilter(folderFilter);
271: }
272: if (rootFolder != null) {
273: customEditor.setRootObject(rootFolder);
274: }
275: if (rootNode != null) {
276: customEditor.setRootNode(rootNode);
277: }
278: if (insets != null) {
279: customEditor.setInsetValue(insets.intValue());
280: }
281: if (description != null) {
282: customEditor.setDescription(description);
283: }
284: if (selectionMode != null) {
285: customEditor.setSelectionMode(selectionMode.intValue());
286: }
287: customEditor.setMultiSelection(false);
288: return customEditor;
289: }
290:
291: /**
292: * Determines whether the propertyEditor can provide a custom editor.
293: * @return true.
294: */
295: public boolean supportsCustomEditor() {
296: return true;
297: }
298:
299: /** Adds the listener also to private support supp.*/
300: public void addPropertyChangeListener(PropertyChangeListener l) {
301: super .addPropertyChangeListener(l);
302: supp.addPropertyChangeListener(l);
303: }
304:
305: /** Removes the listener also from private support supp.*/
306: public void removePropertyChangeListener(PropertyChangeListener l) {
307: super .removePropertyChangeListener(l);
308: supp.removePropertyChangeListener(l);
309: }
310:
311: public String getAsText() {
312: Object value = getValue();
313: if (value instanceof DataObject) {
314: return ((DataObject) value).getNodeDelegate()
315: .getDisplayName();
316: }
317: return "";
318: }
319:
320: public void setAsText(String text)
321: throws java.lang.IllegalArgumentException {
322: if ((text == null) || ("".equals(text)))
323: setValue(null);
324: }
325:
326: /** CookieFilter allows you to filter DataObjects
327: * based on presence of specified cookies.
328: */
329: private static class CookieFilter implements DataFilter {
330: private Class[] cookieArray;
331: private DataFilter originalFilter;
332:
333: /** Just remember the cookie array and original filter.*/
334: public CookieFilter(Class[] cookieArray,
335: DataFilter originalFilter) {
336: this .cookieArray = cookieArray;
337: this .originalFilter = originalFilter;
338: }
339:
340: /** Should the data object be displayed or not? This implementation
341: * combines the originalFilter with set of cookies supplied
342: * in cookieArray.
343: * @param obj the data object
344: * @return <CODE>true</CODE> if the object should be displayed,
345: * <CODE>false</CODE> otherwise
346: */
347: public boolean acceptDataObject(DataObject obj) {
348: if (cookieArray == null) {
349: if (originalFilter != null) {
350: return originalFilter.acceptDataObject(obj);
351: } else {
352: return true;
353: }
354: }
355: for (int i = 0; i < cookieArray.length; i++) {
356: if (obj.getCookie(cookieArray[i]) == null) {
357: return false;
358: }
359: }
360: if (originalFilter != null) {
361: return originalFilter.acceptDataObject(obj);
362: } else {
363: return true;
364: }
365: }
366: }
367: }
|