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.web.wizards;
043:
044: import java.awt.Dialog;
045: import java.awt.event.ActionEvent;
046: import java.awt.event.ActionListener;
047: import java.util.ArrayList;
048: import java.util.Arrays;
049: import java.util.Collection;
050: import java.util.Collections;
051: import javax.swing.JButton;
052: import javax.swing.JScrollPane;
053: import org.netbeans.api.project.SourceGroup;
054: import org.openide.util.NbBundle;
055: import org.openide.DialogDescriptor;
056: import org.openide.DialogDisplayer;
057: import org.openide.explorer.ExplorerManager;
058: import org.openide.explorer.view.BeanTreeView;
059: import org.openide.filesystems.FileObject;
060: import org.openide.loaders.DataObject;
061: import org.openide.loaders.DataObjectNotFoundException;
062: import org.openide.loaders.DataFolder;
063: import org.openide.nodes.Children;
064: import org.openide.nodes.Node;
065: import org.openide.nodes.AbstractNode;
066: import org.openide.nodes.FilterNode;
067: import org.openide.nodes.NodeNotFoundException;
068: import org.openide.nodes.NodeOp;
069: import org.openide.util.NbCollections;
070:
071: // XXX I18N
072:
073: /**
074: *
075: * @author phrebejk, mkuchtiak
076: */
077: public class BrowseFolders extends javax.swing.JPanel implements
078: ExplorerManager.Provider {
079:
080: private ExplorerManager manager;
081: private SourceGroup[] folders;
082: private Class target;
083: BeanTreeView btv;
084:
085: private static JScrollPane SAMPLE_SCROLL_PANE = new JScrollPane();
086:
087: /** Creates new form BrowseFolders */
088: public BrowseFolders(SourceGroup[] folders, Class target,
089: String preselectedFileName) {
090: initComponents();
091: getAccessibleContext()
092: .setAccessibleDescription(
093: NbBundle
094: .getMessage(
095: BrowseFolders.class,
096: (target == DataFolder.class ? "ACSD_BrowseFolders"
097: : "ACSD_BrowseFiles")));
098:
099: this .folders = folders;
100: this .target = target;
101: manager = new ExplorerManager();
102: AbstractNode rootNode = new AbstractNode(
103: new SourceGroupsChildren(folders));
104: manager.setRootContext(rootNode);
105:
106: // Create the templates view
107: btv = new BeanTreeView();
108: btv.setRootVisible(false);
109: btv
110: .setSelectionMode(javax.swing.tree.TreeSelectionModel.SINGLE_TREE_SELECTION);
111: btv.setBorder(SAMPLE_SCROLL_PANE.getBorder());
112: expandSelection(preselectedFileName);
113: folderPanel.add(btv, java.awt.BorderLayout.CENTER);
114: }
115:
116: // ExplorerManager.Provider implementation ---------------------------------
117:
118: public ExplorerManager getExplorerManager() {
119: return manager;
120: }
121:
122: private void expandSelection(String preselectedFileName) {
123:
124: Node root = manager.getRootContext();
125: Children ch = root.getChildren();
126: if (ch == Children.LEAF) {
127: return;
128: }
129: Node nodes[] = ch.getNodes(true);
130:
131: Node sel = null;
132:
133: if (preselectedFileName != null
134: && preselectedFileName.length() > 0) {
135: // Try to find the node
136: for (int i = 0; i < nodes.length; i++) {
137: try {
138: sel = NodeOp.findPath(nodes[i], NbCollections
139: .checkedEnumerationByFilter(
140: new java.util.StringTokenizer(
141: preselectedFileName, "/"),
142: String.class, false));
143: break;
144: } catch (NodeNotFoundException e) {
145: // Will select the first node
146: }
147: }
148: }
149:
150: if (sel == null) {
151: // Node not found => expand first level
152: btv.expandNode(root);
153: for (int i = 0; i < nodes.length; i++) {
154: btv.expandNode(nodes[i]);
155: if (i == 0) {
156: sel = nodes[i];
157: }
158: }
159: }
160:
161: if (sel != null) {
162: // Select the node
163: try {
164: manager.setSelectedNodes(new Node[] { sel });
165: } catch (java.beans.PropertyVetoException e) {
166: // No selection for some reason
167: }
168: }
169:
170: }
171:
172: /** This method is called from within the constructor to
173: * initialize the form.
174: * WARNING: Do NOT modify this code. The content of this method is
175: * always regenerated by the Form Editor.
176: */
177: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
178: private void initComponents() {
179: java.awt.GridBagConstraints gridBagConstraints;
180:
181: jLabel1 = new javax.swing.JLabel();
182: folderPanel = new javax.swing.JPanel();
183:
184: setLayout(new java.awt.GridBagLayout());
185:
186: setBorder(new javax.swing.border.EmptyBorder(
187: new java.awt.Insets(12, 12, 12, 12)));
188: org.openide.awt.Mnemonics.setLocalizedText(jLabel1,
189: org.openide.util.NbBundle.getMessage(
190: BrowseFolders.class, "LBL_Folders"));
191: gridBagConstraints = new java.awt.GridBagConstraints();
192: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
193: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
194: gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0);
195: add(jLabel1, gridBagConstraints);
196:
197: folderPanel.setLayout(new java.awt.BorderLayout());
198:
199: gridBagConstraints = new java.awt.GridBagConstraints();
200: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
201: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
202: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
203: gridBagConstraints.weightx = 1.0;
204: gridBagConstraints.weighty = 1.0;
205: add(folderPanel, gridBagConstraints);
206:
207: }
208:
209: // </editor-fold>//GEN-END:initComponents
210:
211: // Variables declaration - do not modify//GEN-BEGIN:variables
212: private javax.swing.JPanel folderPanel;
213: private javax.swing.JLabel jLabel1;
214:
215: // End of variables declaration//GEN-END:variables
216:
217: public static FileObject showDialog(SourceGroup[] folders,
218: Class target, String preselectedFileName) {
219:
220: BrowseFolders bf = new BrowseFolders(folders, target,
221: preselectedFileName);
222:
223: JButton selectButton = new JButton(NbBundle.getMessage(
224: BrowseFolders.class,
225: (target == DataFolder.class ? "LBL_SelectFolder"
226: : "LBL_SelectFile")));
227: selectButton
228: .getAccessibleContext()
229: .setAccessibleDescription(
230: NbBundle
231: .getMessage(
232: BrowseFolders.class,
233: (target == DataFolder.class ? "ACSD_SelectFolder"
234: : "ACSD_SelectFile")));
235: JButton cancelButton = new JButton(NbBundle.getMessage(
236: BrowseFolders.class, "LBL_Cancel"));
237: cancelButton.getAccessibleContext()
238: .setAccessibleDescription(
239: NbBundle.getMessage(BrowseFolders.class,
240: "ACSD_Cancel"));
241: JButton options[] = new JButton[] {
242: //new JButton( NbBundle.getMessage( BrowseFolders.class, "LBL_BrowseFolders_Select_Option") ), // NOI18N
243: //new JButton( NbBundle.getMessage( BrowseFolders.class, "LBL_BrowseFolders_Cancel_Option") ), // NOI18N
244: selectButton, cancelButton, };
245:
246: OptionsListener optionsListener = new OptionsListener(bf,
247: target);
248:
249: options[0].setActionCommand(OptionsListener.COMMAND_SELECT);
250: options[0].addActionListener(optionsListener);
251: options[1].setActionCommand(OptionsListener.COMMAND_CANCEL);
252: options[1].addActionListener(optionsListener);
253:
254: DialogDescriptor dialogDescriptor = new DialogDescriptor(
255: bf, // innerPane
256: NbBundle
257: .getMessage(
258: BrowseFolders.class,
259: (target == DataFolder.class ? "LBL_BrowseFolders"
260: : "LBL_BrowseFiles")), // displayName
261: true, // modal
262: options, // options
263: options[0], // initial value
264: DialogDescriptor.BOTTOM_ALIGN, // options align
265: null, // helpCtx
266: null); // listener
267:
268: dialogDescriptor.setClosingOptions(new Object[] { options[0],
269: options[1] });
270:
271: Dialog dialog = DialogDisplayer.getDefault().createDialog(
272: dialogDescriptor);
273: dialog.show();
274:
275: return optionsListener.getResult();
276:
277: }
278:
279: // Innerclasses ------------------------------------------------------------
280:
281: /** Children to be used to show FileObjects from given SourceGroups
282: */
283:
284: private final class SourceGroupsChildren extends Children.Keys {
285:
286: private SourceGroup[] groups;
287: private SourceGroup group;
288: private FileObject fo;
289:
290: public SourceGroupsChildren(SourceGroup[] groups) {
291: this .groups = groups;
292: }
293:
294: public SourceGroupsChildren(FileObject fo, SourceGroup group) {
295: this .fo = fo;
296: this .group = group;
297: }
298:
299: protected void addNotify() {
300: super .addNotify();
301: setKeys(getKeys());
302: }
303:
304: protected void removeNotify() {
305: setKeys(Collections.EMPTY_SET);
306: super .removeNotify();
307: }
308:
309: protected Node[] createNodes(Object key) {
310:
311: FileObject fObj = null;
312: SourceGroup group = null;
313: boolean isFile = false;
314:
315: if (key instanceof SourceGroup) {
316: fObj = ((SourceGroup) key).getRootFolder();
317: group = (SourceGroup) key;
318: } else if (key instanceof Key) {
319: fObj = ((Key) key).folder;
320: group = ((Key) key).group;
321: if (!fObj.isFolder())
322: isFile = true;
323: }
324:
325: try {
326: DataObject dobj = DataObject.find(fObj);
327: FilterNode fn = (isFile ? new FilterNode(dobj
328: .getNodeDelegate(), Children.LEAF)
329: : new FilterNode(dobj.getNodeDelegate(),
330: new SourceGroupsChildren(fObj, group)));
331:
332: if (key instanceof SourceGroup) {
333: fn.setDisplayName(group.getDisplayName());
334: }
335:
336: return new Node[] { fn };
337: } catch (DataObjectNotFoundException e) {
338: return null;
339: }
340: }
341:
342: private Collection getKeys() {
343:
344: if (groups != null) {
345: return Arrays.asList(groups);
346: } else {
347: FileObject files[] = fo.getChildren();
348: Arrays.sort(files,
349: new BrowseFolders.FileObjectComparator());
350: ArrayList children = new ArrayList(files.length);
351:
352: if (BrowseFolders.this .target == org.openide.loaders.DataFolder.class)
353: for (int i = 0; i < files.length; i++) {
354: if (files[i].isFolder()
355: && group.contains(files[i])) {
356: children.add(new Key(files[i], group));
357: }
358: }
359: else {
360: // add folders
361: for (int i = 0; i < files.length; i++) {
362: if (group.contains(files[i])
363: && files[i].isFolder())
364: children.add(new Key(files[i], group));
365: }
366: // add files
367: for (int i = 0; i < files.length; i++) {
368: if (group.contains(files[i])
369: && !files[i].isFolder())
370: children.add(new Key(files[i], group));
371: }
372: }
373:
374: return children;
375: }
376:
377: }
378:
379: private class Key {
380:
381: private FileObject folder;
382: private SourceGroup group;
383:
384: private Key(FileObject folder, SourceGroup group) {
385: this .folder = folder;
386: this .group = group;
387: }
388:
389: }
390:
391: }
392:
393: private class FileObjectComparator implements java.util.Comparator {
394: public int compare(Object o1, Object o2) {
395: FileObject fo1 = (FileObject) o1;
396: FileObject fo2 = (FileObject) o2;
397: return fo1.getName().compareTo(fo2.getName());
398: }
399: }
400:
401: private static final class OptionsListener implements
402: ActionListener {
403:
404: public static final String COMMAND_SELECT = "SELECT"; //NOI18N
405: public static final String COMMAND_CANCEL = "CANCEL"; //NOI18N
406:
407: private BrowseFolders browsePanel;
408:
409: private FileObject result;
410: private Class target;
411:
412: public OptionsListener(BrowseFolders browsePanel, Class target) {
413: this .browsePanel = browsePanel;
414: this .target = target;
415: }
416:
417: public void actionPerformed(ActionEvent e) {
418: String command = e.getActionCommand();
419:
420: if (COMMAND_SELECT.equals(command)) {
421: Node selection[] = browsePanel.getExplorerManager()
422: .getSelectedNodes();
423:
424: if (selection != null && selection.length > 0) {
425: DataObject dobj = (DataObject) selection[0]
426: .getLookup().lookup(DataObject.class);
427: if (dobj != null
428: && dobj.getClass().isAssignableFrom(target)) {
429: result = dobj.getPrimaryFile();
430: }
431: /*
432: if ( dobj != null ) {
433: FileObject fo = dobj.getPrimaryFile();
434: if ( fo.isFolder() ) {
435: result = fo;
436: }
437: }
438: */
439: }
440:
441: }
442: }
443:
444: public FileObject getResult() {
445: return result;
446: }
447: }
448:
449: }
|