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.awt.*;
045: import java.beans.*;
046: import java.util.*;
047: import javax.swing.*;
048: import javax.swing.border.*;
049: import javax.swing.event.*;
050: import javax.swing.tree.*;
051:
052: import org.openide.*;
053: import org.openide.explorer.*;
054: import org.openide.explorer.propertysheet.PropertyEnv;
055: import org.openide.explorer.propertysheet.editors.*;
056: import org.openide.explorer.view.*;
057: import org.openide.loaders.*;
058: import org.openide.nodes.*;
059: import org.openide.util.*;
060:
061: /**
062: * Component that displays an explorer that displays only certain
063: * nodes. Similar to the node selector (retrieved from the TopManager)
064: * but arranged a bit differently, plus allows the user to set the
065: * currently selected node.
066: * @author Joe Warzecha
067: */
068: public class DataObjectPanel extends JPanel {
069:
070: final static int DEFAULT_INSET = 10;
071:
072: protected DataFilter folderFilter;
073: protected DataFilter dataFilter;
074: protected NodeAcceptor nodeFilter;
075: protected Insets insets;
076: protected String subTitle;
077: protected String description;
078: protected DataObject rootObject;
079:
080: protected Node rootNode;
081: protected DataObject dObj;
082: /** Set to true when panel is used by DataObjectArrayEditor. Relevant only
083: * for list view. Tree view allows only single selection. */
084: protected boolean multiSelection;
085: protected int selectionMode = JFileChooser.FILES_ONLY;
086:
087: protected PropertyEditorSupport myEditor;
088:
089: private PropertyEnv env;
090:
091: public DataObjectPanel(PropertyEditorSupport my, PropertyEnv env) {
092: this .env = env;
093: myEditor = my;
094: }
095:
096: /** Allows the panel to be redisplayed in a new dialog controlled
097: * by a new PropertyEnv. */
098: public void setEnv(PropertyEnv env) {
099: this .env = env;
100: }
101:
102: /**
103: * Set the data filter used to filter the nodes displayed.
104: * An example of a DataFilter is one that only returns 'true'
105: * for JavaDataObjects so that only nodes representing those
106: * objects are displayed in the Explorer.
107: *
108: * @param df The DataFilter used to filter nodes
109: */
110: public void setDataFilter(DataFilter df) {
111: dataFilter = df;
112: }
113:
114: /**
115: * Set the Node filter used to filter nodes. For example,
116: * if a user wants to display only JavaDataObjects, but not
117: * any subnodes under those DataNodes, then set the node
118: * filter to not accept any sub nodes.
119: *
120: * @param acceptor The NodeAcceptor used to filter subnodes.
121: */
122: public void setNodeFilter(NodeAcceptor acceptor) {
123: nodeFilter = acceptor;
124: }
125:
126: /**
127: * Set the insets of the Explorer panel.
128: *
129: * @param insetVal The value used for all of the insets (top,
130: * bottom, left, right).
131: */
132: public void setInsetValue(int insetVal) {
133: insets = new Insets(insetVal, insetVal, insetVal, insetVal);
134: }
135:
136: /**
137: * Set explanation text displayed above the Explorer. If
138: * not set, no text is displayed.
139: *
140: * @param text Text displayed on the GUI above the Explorer.
141: */
142: public void setText(String text) {
143: subTitle = text;
144: }
145:
146: /**
147: * Sets the root object displayed on the Explorer. If
148: * not set, then the normal 'FileSystems' node is displayed
149: * as the Root.
150: *
151: * @param obj The DataObject used as the root node on the
152: * Explorer.
153: */
154: public void setRootObject(DataObject obj) {
155: rootObject = obj;
156: }
157:
158: public void setRootNode(Node n) {
159: rootNode = n;
160: }
161:
162: /**
163: * This filter can be used to filter folders.
164: * It is applied before the data filter.
165: */
166: public void setFolderFilter(DataFilter f) {
167: folderFilter = f;
168: }
169:
170: /**
171: * This filter can be used to filter folders.
172: * It is applied before the data filter.
173: */
174: public DataFilter getFolderFilter() {
175: return folderFilter;
176: }
177:
178: /**
179: * Sets the currently selected DataObject.
180: *
181: * @param d The DataObject to be selected in the Explorer.
182: */
183: public void setDataObject(DataObject d) {
184: dObj = d;
185: }
186:
187: /**
188: * Sets selection mode for dialog. It is valid only for list view GUI (JFileChooser).
189: * It is set to false when used by DataObjectEditor and to true when used by
190: * DataObjectArrayEditor.
191: *
192: * @param multiSelection True if multiple object selection is enabled.
193: */
194: public void setMultiSelection(boolean multiSelection) {
195: this .multiSelection = multiSelection;
196: }
197:
198: /**
199: * Sets selection mode for JFileChooser. It is valid only for list view GUI (JFileChooser).
200: * Valid values are:
201: * JFileChooser.FILES_ONLY
202: * JFileChooser.DIRECTORIES_ONLY
203: * JFileChooser.FILES_AND_DIRECTORIES
204: *
205: * @param selectionMode integer value controling if files, directories or both can be
206: * selected in dialog
207: */
208: public void setSelectionMode(int selectionMode) {
209: this .selectionMode = selectionMode;
210: }
211:
212: /**
213: * Sets description of the panel.
214: *
215: * @param desc Desciption of the panel.
216: */
217: public void setDescription(String desc) {
218: }
219:
220: protected Node findNode(Node parent, DataObject val) {
221: Children children = parent.getChildren();
222: Node theNode = children.findChild(val.getName());
223: if (theNode == null) {
224: Node[] allNodes = children.getNodes();
225: if ((allNodes != null) && (allNodes.length > 0)) {
226: for (int i = 0; (i < allNodes.length)
227: && (theNode == null); i++) {
228: DataObject dObj = (DataObject) allNodes[i]
229: .getCookie(DataObject.class);
230: if ((dObj != null) && (dObj == val)) {
231: theNode = allNodes[i];
232: }
233: }
234: }
235: }
236:
237: return theNode;
238: }
239:
240: protected Node findNodeForObj(Node rootNode, DataObject dObj) {
241: Node node = null;
242: DataFolder df = dObj.getFolder();
243: Vector<DataFolder> v = new Vector<DataFolder>();
244: while (df != null) {
245: v.addElement(df);
246: df = df.getFolder();
247: }
248:
249: if (!v.isEmpty()) {
250: Node parent = findParentNode(v, rootNode.getChildren());
251: if (parent != null) {
252: node = findNode(parent, dObj);
253: } else {
254: node = findNode(rootNode, dObj);
255: }
256: } else {
257: node = findNode(rootNode, dObj);
258: }
259:
260: return node;
261: }
262:
263: protected Node findParentNode(Vector<DataFolder> v,
264: Children children) {
265: DataFolder df = v.lastElement();
266:
267: //Node n = children.findChild (df.getPrimaryFile ().getName ());
268: Node n = children.findChild(df.getNodeDelegate().getName());
269: if (n == null) {
270: Node[] nodes = children.getNodes();
271: for (int i = 0; (i < nodes.length) && (n == null); i++) {
272: DataFolder folder = (DataFolder) nodes[i]
273: .getCookie(DataFolder.class);
274: if ((folder != null) && (folder == df)) {
275: n = nodes[i];
276: }
277: }
278: }
279:
280: if (v.size() > 1) {
281: v.removeElement(df);
282: if (n != null) {
283: return findParentNode(v, n.getChildren());
284: } else {
285: // Didn't find it, try next folder anyway
286: return findParentNode(v, children);
287: }
288: }
289: return n;
290: }
291:
292: /**
293: * Return the currently selected DataObject.
294: * @return The currently selected DataObject or null if there is no node seleted
295: */
296: public DataObject getDataObject() {
297: return null;
298: }
299:
300: /**
301: * Return the currently selected Node.
302: * @return The currently selected Node or null if there is no node seleted
303: */
304: public Node getNode() {
305: return null;
306: }
307:
308: /** Get the customized property value.
309: * @return the property value
310: * @exception InvalidStateException when the custom property editor does not contain a valid property value
311: * (and thus it should not be set)
312: */
313: public Object getPropertyValue() throws IllegalStateException {
314: return getDataObject();
315: }
316:
317: protected void setOkButtonEnabled(boolean b) {
318: if (env != null) {
319: env.setState(b ? env.STATE_VALID : env.STATE_INVALID);
320: }
321: }
322:
323: static class FilteredChildren extends FilterNode.Children {
324: private NodeAcceptor nodeAcceptor;
325: private DataFilter dFilter;
326:
327: FilteredChildren(Node n, NodeAcceptor acceptor,
328: DataFilter filter) {
329: super (n);
330: nodeAcceptor = acceptor;
331: dFilter = filter;
332: }
333:
334: private Node[] makeFilterNode(Node n) {
335: FilteredChildren children = new FilteredChildren(n,
336: nodeAcceptor, dFilter);
337: return new Node[] { new FilterNode(n, children) };
338: }
339:
340: @Override
341: protected Node[] createNodes(Node key) {
342: if (key != null) {
343: Node[] n = new Node[] { key };
344: if (dFilter != null) {
345: DataObject dObj = (DataObject) n[0]
346: .getCookie(DataObject.class);
347: if ((dObj != null)
348: && (dFilter.acceptDataObject(dObj))) {
349: return makeFilterNode(n[0]);
350: }
351: }
352:
353: if (nodeAcceptor.acceptNodes(n)) {
354: return makeFilterNode(n[0]);
355: }
356: }
357: return new Node[0];
358: }
359: }
360:
361: }
|