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.Component;
045: import java.awt.event.ActionListener;
046: import java.io.File;
047: import java.text.MessageFormat;
048: import javax.swing.DefaultComboBoxModel;
049: import javax.swing.JLabel;
050: import javax.swing.JList;
051: import javax.swing.ListCellRenderer;
052: import javax.swing.event.ChangeListener;
053: import javax.swing.event.DocumentListener;
054: import org.netbeans.api.project.Project;
055: import org.netbeans.api.project.ProjectUtils;
056: import org.netbeans.api.project.SourceGroup;
057: import org.netbeans.api.project.Sources;
058: import org.openide.awt.Mnemonics;
059: import org.openide.filesystems.FileObject;
060: import org.openide.filesystems.FileUtil;
061: import org.openide.loaders.DataObject;
062: import org.openide.loaders.DataObjectNotFoundException;
063: import org.openide.util.ChangeSupport;
064: import org.openide.util.NbBundle;
065:
066: /**
067: *
068: * @author phrebejk
069: */
070: public class SimpleTargetChooserPanelGUI extends javax.swing.JPanel
071: implements ActionListener, DocumentListener {
072:
073: /** prefered dimmension of the panels */
074: private static final java.awt.Dimension PREF_DIM = new java.awt.Dimension(
075: 500, 340);
076:
077: private static final String NEW_FILE_PREFIX = NbBundle.getMessage(
078: SimpleTargetChooserPanelGUI.class,
079: "LBL_SimpleTargetChooserPanelGUI_NewFilePrefix"); // NOI18N
080:
081: private final ListCellRenderer CELL_RENDERER = new GroupCellRenderer();
082:
083: private Project project;
084: private String expectedExtension;
085: private final ChangeSupport changeSupport = new ChangeSupport(this );
086: private SourceGroup[] folders;
087: private boolean isFolder;
088:
089: /** Creates new form SimpleTargetChooserGUI */
090: public SimpleTargetChooserPanelGUI(Project project,
091: SourceGroup[] folders, Component bottomPanel,
092: boolean isFolder) {
093: this .project = project;
094: this .folders = folders;
095: this .isFolder = isFolder;
096: initComponents();
097:
098: locationComboBox.setRenderer(CELL_RENDERER);
099:
100: if (bottomPanel != null) {
101: bottomPanelContainer.add(bottomPanel,
102: java.awt.BorderLayout.CENTER);
103: }
104: initValues(null, null, null);
105:
106: browseButton.addActionListener(this );
107: locationComboBox.addActionListener(this );
108: documentNameTextField.getDocument().addDocumentListener(this );
109: folderTextField.getDocument().addDocumentListener(this );
110:
111: setName(NbBundle.getMessage(SimpleTargetChooserPanelGUI.class,
112: "LBL_SimpleTargetChooserPanel_Name")); // NOI18N
113: }
114:
115: public void initValues(FileObject template,
116: FileObject preselectedFolder, String documentName) {
117: assert project != null;
118:
119: projectTextField.setText(ProjectUtils.getInformation(project)
120: .getDisplayName());
121:
122: Sources sources = ProjectUtils.getSources(project);
123:
124: folders = sources.getSourceGroups(Sources.TYPE_GENERIC);
125:
126: if (folders.length < 2) {
127: // one source group i.e. hide Location
128: locationLabel.setVisible(false);
129: locationComboBox.setVisible(false);
130: } else {
131: // more source groups user needs to select location
132: locationLabel.setVisible(true);
133: locationComboBox.setVisible(true);
134:
135: }
136:
137: locationComboBox.setModel(new DefaultComboBoxModel(folders));
138: // Guess the group we want to create the file in
139: SourceGroup preselectedGroup = getPreselectedGroup(folders,
140: preselectedFolder);
141: locationComboBox.setSelectedItem(preselectedGroup);
142: // Create OS dependent relative name
143: folderTextField.setText(getRelativeNativeName(preselectedGroup
144: .getRootFolder(), preselectedFolder));
145:
146: String ext = template == null ? "" : template.getExt(); // NOI18N
147: expectedExtension = ext.length() == 0 ? "" : "." + ext; // NOI18N
148:
149: String displayName = null;
150: try {
151: if (template != null) {
152: DataObject templateDo = DataObject.find(template);
153: displayName = templateDo.getNodeDelegate()
154: .getDisplayName();
155: }
156: } catch (DataObjectNotFoundException ex) {
157: displayName = template.getName();
158: }
159: putClientProperty("NewFileWizard_Title", displayName);// NOI18N
160: if (template != null) {
161: final String baseName = NEW_FILE_PREFIX
162: + template.getName();
163: if (documentName == null) {
164: documentName = baseName;
165: }
166: if (preselectedFolder != null) {
167: int index = 0;
168: while (true) {
169: FileObject _tmp = preselectedFolder.getFileObject(
170: documentName, template.getExt());
171: if (_tmp == null) {
172: break;
173: }
174: documentName = baseName + ++index;
175: }
176: }
177:
178: documentNameTextField.setText(documentName);
179: documentNameTextField.selectAll();
180: }
181:
182: if (isFolder) {
183: Mnemonics.setLocalizedText(jLabel3, NbBundle.getMessage(
184: SimpleTargetChooserPanelGUI.class,
185: "LBL_TargetChooser_FolderName_Label")); // NOI18N
186: Mnemonics.setLocalizedText(jLabel2, NbBundle.getMessage(
187: SimpleTargetChooserPanelGUI.class,
188: "LBL_TargetChooser_ParentFolder_Label")); // NOI18N
189: Mnemonics.setLocalizedText(jLabel4, NbBundle.getMessage(
190: SimpleTargetChooserPanelGUI.class,
191: "LBL_TargetChooser_CreatedFolder_Label")); // NOI18N
192: } else {
193: Mnemonics.setLocalizedText(jLabel3, NbBundle.getMessage(
194: SimpleTargetChooserPanelGUI.class,
195: "LBL_TargetChooser_FileName_Label")); // NOI18N
196: Mnemonics.setLocalizedText(jLabel2, NbBundle.getMessage(
197: SimpleTargetChooserPanelGUI.class,
198: "LBL_TargetChooser_Folder_Label")); // NOI18N
199: Mnemonics.setLocalizedText(jLabel4, NbBundle.getMessage(
200: SimpleTargetChooserPanelGUI.class,
201: "LBL_TargetChooser_CreatedFile_Label")); // NOI18N
202: }
203: }
204:
205: public SourceGroup getTargetGroup() {
206: return (SourceGroup) locationComboBox.getSelectedItem();
207: }
208:
209: public String getTargetFolder() {
210:
211: String folderName = folderTextField.getText().trim();
212:
213: if (folderName.length() == 0) {
214: return null;
215: } else {
216: return folderName.replace(File.separatorChar, '/'); // NOI18N
217: }
218: }
219:
220: public String getTargetName() {
221:
222: String text = documentNameTextField.getText().trim();
223:
224: if (text.length() == 0) {
225: return null;
226: } else {
227: return text;
228: }
229: }
230:
231: @Override
232: public java.awt.Dimension getPreferredSize() {
233: return PREF_DIM;
234: }
235:
236: public void addChangeListener(ChangeListener l) {
237: changeSupport.addChangeListener(l);
238: }
239:
240: public void removeChangeListener(ChangeListener l) {
241: changeSupport.removeChangeListener(l);
242: }
243:
244: /** This method is called from within the constructor to
245: * initialize the form.
246: * WARNING: Do NOT modify this code. The content of this method is
247: * always regenerated by the Form Editor.
248: */
249: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
250: private void initComponents() {
251: java.awt.GridBagConstraints gridBagConstraints;
252:
253: jPanel1 = new javax.swing.JPanel();
254: jLabel3 = new javax.swing.JLabel();
255: documentNameTextField = new javax.swing.JTextField();
256: jLabel1 = new javax.swing.JLabel();
257: projectTextField = new javax.swing.JTextField();
258: locationLabel = new javax.swing.JLabel();
259: locationComboBox = new javax.swing.JComboBox();
260: jLabel2 = new javax.swing.JLabel();
261: folderTextField = new javax.swing.JTextField();
262: browseButton = new javax.swing.JButton();
263: jLabel4 = new javax.swing.JLabel();
264: fileTextField = new javax.swing.JTextField();
265: targetSeparator = new javax.swing.JSeparator();
266: bottomPanelContainer = new javax.swing.JPanel();
267:
268: setLayout(new java.awt.GridBagLayout());
269:
270: jPanel1.setLayout(new java.awt.GridBagLayout());
271:
272: jLabel3.setLabelFor(documentNameTextField);
273: org.openide.awt.Mnemonics.setLocalizedText(jLabel3,
274: org.openide.util.NbBundle.getMessage(
275: SimpleTargetChooserPanelGUI.class,
276: "LBL_TargetChooser_FileName_Label")); // NOI18N
277: gridBagConstraints = new java.awt.GridBagConstraints();
278: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
279: jPanel1.add(jLabel3, gridBagConstraints);
280: gridBagConstraints = new java.awt.GridBagConstraints();
281: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
282: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
283: gridBagConstraints.weightx = 1.0;
284: gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 0);
285: jPanel1.add(documentNameTextField, gridBagConstraints);
286: documentNameTextField.getAccessibleContext()
287: .setAccessibleDescription(
288: org.openide.util.NbBundle.getBundle(
289: SimpleTargetChooserPanelGUI.class)
290: .getString("AD_documentNameTextField")); // NOI18N
291:
292: gridBagConstraints = new java.awt.GridBagConstraints();
293: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
294: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
295: gridBagConstraints.insets = new java.awt.Insets(0, 0, 24, 0);
296: add(jPanel1, gridBagConstraints);
297:
298: jLabel1.setLabelFor(projectTextField);
299: org.openide.awt.Mnemonics.setLocalizedText(jLabel1,
300: org.openide.util.NbBundle.getMessage(
301: SimpleTargetChooserPanelGUI.class,
302: "LBL_TargetChooser_Project_Label")); // NOI18N
303: gridBagConstraints = new java.awt.GridBagConstraints();
304: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
305: gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 0);
306: add(jLabel1, gridBagConstraints);
307:
308: projectTextField.setEditable(false);
309: gridBagConstraints = new java.awt.GridBagConstraints();
310: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
311: gridBagConstraints.weightx = 1.0;
312: gridBagConstraints.insets = new java.awt.Insets(0, 6, 6, 0);
313: add(projectTextField, gridBagConstraints);
314: projectTextField.getAccessibleContext()
315: .setAccessibleDescription(
316: org.openide.util.NbBundle.getBundle(
317: SimpleTargetChooserPanelGUI.class)
318: .getString("AD_projectTextField")); // NOI18N
319:
320: locationLabel.setLabelFor(locationComboBox);
321: org.openide.awt.Mnemonics.setLocalizedText(locationLabel,
322: org.openide.util.NbBundle.getMessage(
323: SimpleTargetChooserPanelGUI.class,
324: "LBL_TargetChooser_Location_Label")); // NOI18N
325: gridBagConstraints = new java.awt.GridBagConstraints();
326: gridBagConstraints.gridy = 2;
327: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
328: gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
329: add(locationLabel, gridBagConstraints);
330: gridBagConstraints = new java.awt.GridBagConstraints();
331: gridBagConstraints.gridy = 2;
332: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
333: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
334: gridBagConstraints.insets = new java.awt.Insets(0, 6, 5, 0);
335: add(locationComboBox, gridBagConstraints);
336: locationComboBox.getAccessibleContext()
337: .setAccessibleDescription(
338: org.openide.util.NbBundle.getBundle(
339: SimpleTargetChooserPanelGUI.class)
340: .getString("AD_locationComboBox")); // NOI18N
341:
342: jLabel2.setLabelFor(folderTextField);
343: org.openide.awt.Mnemonics.setLocalizedText(jLabel2,
344: org.openide.util.NbBundle.getMessage(
345: SimpleTargetChooserPanelGUI.class,
346: "LBL_TargetChooser_Folder_Label")); // NOI18N
347: gridBagConstraints = new java.awt.GridBagConstraints();
348: gridBagConstraints.gridx = 0;
349: gridBagConstraints.gridy = 3;
350: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
351: gridBagConstraints.insets = new java.awt.Insets(0, 0, 12, 0);
352: add(jLabel2, gridBagConstraints);
353: gridBagConstraints = new java.awt.GridBagConstraints();
354: gridBagConstraints.gridy = 3;
355: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
356: gridBagConstraints.weightx = 1.0;
357: gridBagConstraints.insets = new java.awt.Insets(0, 6, 12, 0);
358: add(folderTextField, gridBagConstraints);
359: folderTextField.getAccessibleContext()
360: .setAccessibleDescription(
361: org.openide.util.NbBundle.getBundle(
362: SimpleTargetChooserPanelGUI.class)
363: .getString("AD_folderTextField")); // NOI18N
364:
365: org.openide.awt.Mnemonics.setLocalizedText(browseButton,
366: org.openide.util.NbBundle.getMessage(
367: SimpleTargetChooserPanelGUI.class,
368: "LBL_TargetChooser_Browse_Button")); // NOI18N
369: gridBagConstraints = new java.awt.GridBagConstraints();
370: gridBagConstraints.gridy = 3;
371: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
372: gridBagConstraints.insets = new java.awt.Insets(0, 6, 12, 0);
373: add(browseButton, gridBagConstraints);
374: browseButton.getAccessibleContext().setAccessibleDescription(
375: org.openide.util.NbBundle.getBundle(
376: SimpleTargetChooserPanelGUI.class).getString(
377: "AD_browseButton")); // NOI18N
378:
379: jLabel4.setLabelFor(fileTextField);
380: org.openide.awt.Mnemonics.setLocalizedText(jLabel4,
381: org.openide.util.NbBundle.getMessage(
382: SimpleTargetChooserPanelGUI.class,
383: "LBL_TargetChooser_CreatedFile_Label")); // NOI18N
384: gridBagConstraints = new java.awt.GridBagConstraints();
385: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
386: gridBagConstraints.insets = new java.awt.Insets(0, 0, 12, 0);
387: add(jLabel4, gridBagConstraints);
388:
389: fileTextField.setEditable(false);
390: gridBagConstraints = new java.awt.GridBagConstraints();
391: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
392: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
393: gridBagConstraints.weightx = 1.0;
394: gridBagConstraints.insets = new java.awt.Insets(0, 6, 12, 0);
395: add(fileTextField, gridBagConstraints);
396: fileTextField.getAccessibleContext().setAccessibleDescription(
397: org.openide.util.NbBundle.getBundle(
398: SimpleTargetChooserPanelGUI.class).getString(
399: "AD_fileTextField")); // NOI18N
400:
401: gridBagConstraints = new java.awt.GridBagConstraints();
402: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
403: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
404: gridBagConstraints.insets = new java.awt.Insets(0, 0, 12, 0);
405: add(targetSeparator, gridBagConstraints);
406:
407: bottomPanelContainer.setLayout(new java.awt.BorderLayout());
408: gridBagConstraints = new java.awt.GridBagConstraints();
409: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
410: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
411: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
412: gridBagConstraints.weighty = 1.0;
413: add(bottomPanelContainer, gridBagConstraints);
414:
415: getAccessibleContext().setAccessibleDescription(
416: org.openide.util.NbBundle.getBundle(
417: SimpleTargetChooserPanelGUI.class).getString(
418: "AD_SimpleTargetChooserPanelGUI")); // NOI18N
419: }// </editor-fold>//GEN-END:initComponents
420:
421: // Variables declaration - do not modify//GEN-BEGIN:variables
422: private javax.swing.JPanel bottomPanelContainer;
423: private javax.swing.JButton browseButton;
424: private javax.swing.JTextField documentNameTextField;
425: private javax.swing.JTextField fileTextField;
426: private javax.swing.JTextField folderTextField;
427: private javax.swing.JLabel jLabel1;
428: private javax.swing.JLabel jLabel2;
429: private javax.swing.JLabel jLabel3;
430: private javax.swing.JLabel jLabel4;
431: private javax.swing.JPanel jPanel1;
432: private javax.swing.JComboBox locationComboBox;
433: private javax.swing.JLabel locationLabel;
434: private javax.swing.JTextField projectTextField;
435: private javax.swing.JSeparator targetSeparator;
436:
437: // End of variables declaration//GEN-END:variables
438:
439: private SourceGroup getPreselectedGroup(SourceGroup[] groups,
440: FileObject folder) {
441: for (int i = 0; folder != null && i < groups.length; i++) {
442: if (FileUtil.isParentOf(groups[i].getRootFolder(), folder)
443: || groups[i].getRootFolder().equals(folder)) {
444: return groups[i];
445: }
446: }
447: return groups[0];
448: }
449:
450: private String getRelativeNativeName(FileObject root,
451: FileObject folder) {
452: if (root == null) {
453: throw new NullPointerException(
454: "null root passed to getRelativeNativeName"); // NOI18N
455: }
456:
457: String path;
458:
459: if (folder == null) {
460: path = ""; // NOI18N
461: } else {
462: path = FileUtil.getRelativePath(root, folder);
463: }
464:
465: return path == null ? "" : path
466: .replace('/', File.separatorChar); // NOI18N
467: }
468:
469: private void updateCreatedFolder() {
470:
471: FileObject root = ((SourceGroup) locationComboBox
472: .getSelectedItem()).getRootFolder();
473:
474: String folderName = folderTextField.getText().trim();
475: String documentName = documentNameTextField.getText().trim();
476:
477: String createdFileName = FileUtil.getFileDisplayName(root)
478: + (folderName.startsWith("/")
479: || folderName.startsWith(File.separator) ? ""
480: : "/")
481: + // NOI18N
482: folderName
483: + (folderName.endsWith("/")
484: || folderName.endsWith(File.separator)
485: || folderName.length() == 0 ? "" : "/") + // NOI18N
486: documentName + expectedExtension;
487:
488: fileTextField.setText(createdFileName.replace('/',
489: File.separatorChar)); // NOI18N
490:
491: changeSupport.fireChange();
492: }
493:
494: // ActionListener implementation -------------------------------------------
495:
496: public void actionPerformed(java.awt.event.ActionEvent e) {
497: if (browseButton == e.getSource()) {
498: FileObject fo = null;
499: // Show the browse dialog
500:
501: SourceGroup group = (SourceGroup) locationComboBox
502: .getSelectedItem();
503:
504: fo = BrowseFolders.showDialog(new SourceGroup[] { group },
505: project, folderTextField.getText().replace(
506: File.separatorChar, '/')); // NOI18N
507:
508: if (fo != null && fo.isFolder()) {
509: String relPath = FileUtil.getRelativePath(group
510: .getRootFolder(), fo);
511: folderTextField.setText(relPath.replace('/',
512: File.separatorChar)); // NOI18N
513: }
514: } else if (locationComboBox == e.getSource()) {
515: updateCreatedFolder();
516: }
517: }
518:
519: // DocumentListener implementation -----------------------------------------
520:
521: public void changedUpdate(javax.swing.event.DocumentEvent e) {
522: updateCreatedFolder();
523: }
524:
525: public void insertUpdate(javax.swing.event.DocumentEvent e) {
526: updateCreatedFolder();
527: }
528:
529: public void removeUpdate(javax.swing.event.DocumentEvent e) {
530: updateCreatedFolder();
531: }
532:
533: // Rendering of the location combo box -------------------------------------
534:
535: private class GroupCellRenderer extends JLabel implements
536: ListCellRenderer {
537:
538: public GroupCellRenderer() {
539: setOpaque(true);
540: }
541:
542: public Component getListCellRendererComponent(JList list,
543: Object value, int index, boolean isSelected,
544: boolean cellHasFocus) {
545: if (value instanceof SourceGroup) {
546: SourceGroup group = (SourceGroup) value;
547: String projectDisplayName = ProjectUtils
548: .getInformation(project).getDisplayName();
549: String groupDisplayName = group.getDisplayName();
550: if (projectDisplayName.equals(groupDisplayName)) {
551: setText(groupDisplayName);
552: } else {
553: setText(MessageFormat.format(
554: PhysicalView.GroupNode.GROUP_NAME_PATTERN,
555: new Object[] { groupDisplayName,
556: projectDisplayName,
557: group.getRootFolder().getName() }));
558: /*
559: setText( MessageFormat.format(
560: NbBundle.getMessage( SimpleTargetChooserPanelGUI.class, "FMT_TargetChooser_GroupProjectNameBadge" ), // NOI18N
561: new Object[] { groupDisplayName, projectDisplayName } ) );
562: */
563: }
564:
565: setIcon(group.getIcon(false));
566: } else {
567: setText(value.toString());
568: setIcon(null);
569: }
570: if (isSelected) {
571: setBackground(list.getSelectionBackground());
572: setForeground(list.getSelectionForeground());
573: } else {
574: setBackground(list.getBackground());
575: setForeground(list.getForeground());
576:
577: }
578: return this;
579: }
580:
581: }
582: }
|