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