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-2007 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.compapp.projects.jbi.ui.wizards;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.text.MessageFormat;
047:
048: import javax.swing.JFileChooser;
049: import javax.swing.event.DocumentEvent;
050: import javax.swing.event.DocumentListener;
051: import javax.swing.text.Document;
052: import org.netbeans.modules.compapp.projects.jbi.ui.FoldersListSettings;
053:
054: import org.netbeans.spi.project.ui.support.ProjectChooser;
055:
056: import org.openide.WizardDescriptor;
057: import org.openide.filesystems.FileUtil;
058: import org.openide.util.NbBundle;
059: import org.openide.util.Utilities;
060:
061: public class PanelProjectLocationVisual extends SettingsPanel implements
062: DocumentListener {
063:
064: private PanelConfigureProject panel;
065:
066: /** Creates new form PanelProjectLocationVisual */
067: public PanelProjectLocationVisual(PanelConfigureProject panel) {
068: initComponents();
069: this .panel = panel;
070:
071: // Register listener on the textFields to make the automatic updates
072: projectNameTextField.getDocument().addDocumentListener(this );
073: projectLocationTextField.getDocument()
074: .addDocumentListener(this );
075: }
076:
077: /** This method is called from within the constructor to
078: * initialize the form.
079: * WARNING: Do NOT modify this code. The content of this method is
080: * always regenerated by the Form Editor.
081: */
082: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
083: private void initComponents() {
084: projectNameLabel = new javax.swing.JLabel();
085: projectNameTextField = new javax.swing.JTextField();
086: projectLocationLabel = new javax.swing.JLabel();
087: projectLocationTextField = new javax.swing.JTextField();
088: Button = new javax.swing.JButton();
089: createdFolderLabel = new javax.swing.JLabel();
090: createdFolderTextField = new javax.swing.JTextField();
091:
092: projectNameLabel.setLabelFor(projectNameTextField);
093: org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel,
094: org.openide.util.NbBundle.getMessage(
095: PanelProjectLocationVisual.class,
096: "LBL_NWP1_ProjectName_Label"));
097:
098: projectNameTextField.getAccessibleContext()
099: .setAccessibleDescription(
100: org.openide.util.NbBundle.getMessage(
101: PanelProjectLocationVisual.class,
102: "ACS_LBL_NWP1_ProjectName_A11YDesc"));
103:
104: projectLocationLabel.setLabelFor(projectLocationTextField);
105: org.openide.awt.Mnemonics.setLocalizedText(
106: projectLocationLabel, org.openide.util.NbBundle
107: .getMessage(PanelProjectLocationVisual.class,
108: "LBL_NWP1_ProjectLocation_Label"));
109:
110: projectLocationTextField
111: .getAccessibleContext()
112: .setAccessibleDescription(
113: org.openide.util.NbBundle
114: .getMessage(
115: PanelProjectLocationVisual.class,
116: "ACS_LBL_NPW1_ProjectLocation_A11YDesc"));
117:
118: org.openide.awt.Mnemonics.setLocalizedText(Button,
119: org.openide.util.NbBundle.getMessage(
120: PanelProjectLocationVisual.class,
121: "LBL_NWP1_BrowseLocation_Button"));
122: Button.setActionCommand("BROWSE");
123: Button.addActionListener(new java.awt.event.ActionListener() {
124: public void actionPerformed(java.awt.event.ActionEvent evt) {
125: browseLocationAction(evt);
126: }
127: });
128:
129: Button.getAccessibleContext().setAccessibleDescription(
130: org.openide.util.NbBundle.getMessage(
131: PanelProjectLocationVisual.class,
132: "ACS_LBL_NWP1_BrowseLocation_A11YDesc"));
133:
134: createdFolderLabel.setLabelFor(createdFolderTextField);
135: org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel,
136: org.openide.util.NbBundle.getMessage(
137: PanelProjectLocationVisual.class,
138: "LBL_NWP1_CreatedProjectFolder_Lablel"));
139:
140: createdFolderTextField.setEditable(false);
141: createdFolderTextField
142: .getAccessibleContext()
143: .setAccessibleDescription(
144: org.openide.util.NbBundle
145: .getMessage(
146: PanelProjectLocationVisual.class,
147: "ACS_LBL_NWP1_CreatedProjectFolder_A11YDesc"));
148:
149: org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
150: this );
151: this .setLayout(layout);
152: layout
153: .setHorizontalGroup(layout
154: .createParallelGroup(
155: org.jdesktop.layout.GroupLayout.LEADING)
156: .add(
157: layout
158: .createSequentialGroup()
159: .addContainerGap()
160: .add(
161: layout
162: .createParallelGroup(
163: org.jdesktop.layout.GroupLayout.LEADING)
164: .add(
165: projectNameLabel)
166: .add(
167: createdFolderLabel)
168: .add(
169: projectLocationLabel))
170: .addPreferredGap(
171: org.jdesktop.layout.LayoutStyle.RELATED)
172: .add(
173: layout
174: .createParallelGroup(
175: org.jdesktop.layout.GroupLayout.LEADING)
176: .add(
177: projectNameTextField,
178: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
179: 248,
180: Short.MAX_VALUE)
181: .add(
182: createdFolderTextField,
183: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
184: 248,
185: Short.MAX_VALUE)
186: .add(
187: org.jdesktop.layout.GroupLayout.TRAILING,
188: projectLocationTextField,
189: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
190: 248,
191: Short.MAX_VALUE))
192: .addPreferredGap(
193: org.jdesktop.layout.LayoutStyle.RELATED)
194: .add(Button)));
195:
196: layout.linkSize(new java.awt.Component[] { createdFolderLabel,
197: projectLocationLabel, projectNameLabel },
198: org.jdesktop.layout.GroupLayout.HORIZONTAL);
199:
200: layout
201: .setVerticalGroup(layout
202: .createParallelGroup(
203: org.jdesktop.layout.GroupLayout.LEADING)
204: .add(
205: layout
206: .createSequentialGroup()
207: .addContainerGap()
208: .add(
209: layout
210: .createParallelGroup(
211: org.jdesktop.layout.GroupLayout.BASELINE)
212: .add(
213: projectNameLabel)
214: .add(
215: projectNameTextField,
216: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
217: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
218: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
219: .add(10, 10, 10)
220: .add(
221: layout
222: .createParallelGroup(
223: org.jdesktop.layout.GroupLayout.BASELINE)
224: .add(
225: projectLocationLabel)
226: .add(
227: projectLocationTextField,
228: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
229: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
230: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
231: .add(Button))
232: .add(5, 5, 5)
233: .add(
234: layout
235: .createParallelGroup(
236: org.jdesktop.layout.GroupLayout.BASELINE)
237: .add(
238: createdFolderLabel)
239: .add(
240: createdFolderTextField,
241: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
242: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
243: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
244: .addContainerGap(
245: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
246: Short.MAX_VALUE)));
247: }// </editor-fold>//GEN-END:initComponents
248:
249: private void browseLocationAction(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseLocationAction
250: String command = evt.getActionCommand();
251:
252: if ("BROWSE".equals(command)) { // NOI18N
253: JFileChooser chooser = new JFileChooser();
254: chooser.setDialogTitle(NbBundle.getMessage(
255: PanelProjectLocationVisual.class,
256: "LBL_NWP1_SelectProjectLocation")); // NOI18N
257: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
258: String path = projectLocationTextField.getText();
259: if (path.length() > 0) {
260: File f = new File(path);
261: if (f.exists())
262: chooser.setSelectedFile(f);
263: }
264: if (JFileChooser.APPROVE_OPTION == chooser
265: .showOpenDialog(this )) {
266: File projectDir = chooser.getSelectedFile();
267: projectLocationTextField.setText(projectDir
268: .getAbsolutePath());
269: }
270: panel.fireChangeEvent();
271: }
272: }//GEN-LAST:event_browseLocationAction
273:
274: public void addNotify() {
275: super .addNotify();
276: //same problem as in 31086, initial focus on Cancel button
277: projectNameTextField.requestFocus();
278: }
279:
280: boolean valid(WizardDescriptor wizardDescriptor) {
281: if (projectNameTextField.getText().length() == 0
282: || projectNameTextField.getText().indexOf('/') > 0 //NOI18N
283: || projectNameTextField.getText().indexOf('\\') > 0 //NOI18N
284: || projectNameTextField.getText().indexOf(':') > 0) { //NOI18N
285: wizardDescriptor.putProperty("WizardPanel_errorMessage", // NOI18N
286: NbBundle.getMessage(
287: PanelProjectLocationVisual.class,
288: "MSG_IllegalProjectName")); // NOI18N
289: return false; // Display name not specified
290: }
291:
292: File f = new File(projectLocationTextField.getText())
293: .getAbsoluteFile();
294: if (getCanonicalFile(f) == null) {
295: String message = NbBundle.getMessage(
296: PanelProjectLocationVisual.class,
297: "MSG_IllegalProjectLocation"); // NOI18N
298: wizardDescriptor.putProperty("WizardPanel_errorMessage",
299: message); // NOI18N
300: return false;
301: }
302: // not allow to create project on unix root folder, see #82339
303: File cfl = getCanonicalFile(new File(createdFolderTextField
304: .getText()));
305: if (Utilities.isUnix() && cfl != null
306: && cfl.getParentFile().getParent() == null) {
307: String message = NbBundle.getMessage(
308: PanelProjectLocationVisual.class,
309: "MSG_ProjectInRootNotSupported"); // NOI18N
310: wizardDescriptor.putProperty("WizardPanel_errorMessage",
311: message); // NOI18N
312: return false;
313: }
314:
315: final File destFolder = new File(createdFolderTextField
316: .getText()).getAbsoluteFile();
317: if (getCanonicalFile(destFolder) == null) {
318: String message = NbBundle.getMessage(
319: PanelProjectLocationVisual.class,
320: "MSG_IllegalProjectLocation"); // NOI18N
321: wizardDescriptor.putProperty("WizardPanel_errorMessage",
322: message); // NOI18N
323: return false;
324: }
325:
326: File projLoc = FileUtil.normalizeFile(destFolder);
327: while (projLoc != null && !projLoc.exists()) {
328: projLoc = projLoc.getParentFile();
329: }
330: if (projLoc == null || !projLoc.canWrite()) {
331: wizardDescriptor.putProperty("WizardPanel_errorMessage", // NOI18N
332: NbBundle.getMessage(
333: PanelProjectLocationVisual.class,
334: "MSG_ProjectFolderReadOnly")); // NOI18N
335: return false;
336: }
337:
338: if (FileUtil.toFileObject(projLoc) == null) {
339: String message = NbBundle.getMessage(
340: PanelProjectLocationVisual.class,
341: "MSG_IllegalProjectLocation"); // NOI18N
342: wizardDescriptor.putProperty("WizardPanel_errorMessage",
343: message); // NOI18N
344: return false;
345: }
346:
347: File[] kids = destFolder.listFiles();
348: if (destFolder.exists() && kids != null && kids.length > 0) {
349: // Folder exists and is not empty
350: wizardDescriptor.putProperty("WizardPanel_errorMessage", // NOI18N
351: NbBundle.getMessage(
352: PanelProjectLocationVisual.class,
353: "MSG_ProjectFolderExists")); // NOI18N
354: return false;
355: }
356:
357: wizardDescriptor.putProperty("WizardPanel_errorMessage", ""); // NOI18N
358: return true;
359: }
360:
361: void store(WizardDescriptor d) {
362: String name = projectNameTextField.getText().trim();
363:
364: d.putProperty(WizardProperties.PROJECT_DIR, new File(
365: createdFolderTextField.getText().trim()));
366: d.putProperty(WizardProperties.NAME, name);
367:
368: File projectsDir = new File(this .projectLocationTextField
369: .getText());
370: if (projectsDir.isDirectory()) {
371: ProjectChooser.setProjectsFolder(projectsDir);
372: }
373: }
374:
375: void read(WizardDescriptor settings) {
376: File projectLocation = (File) settings
377: .getProperty(WizardProperties.PROJECT_DIR);
378: if (projectLocation == null)
379: projectLocation = ProjectChooser.getProjectsFolder();
380: else
381: projectLocation = projectLocation.getParentFile();
382:
383: projectLocationTextField.setText(projectLocation
384: .getAbsolutePath());
385:
386: String projectName = (String) settings
387: .getProperty(WizardProperties.NAME);
388: if (projectName == null) {
389: int baseCount = FoldersListSettings.getDefault()
390: .getNewProjectCount() + 1;
391: String formater = NbBundle.getMessage(
392: PanelProjectLocationVisual.class,
393: "LBL_NPW1_DefaultProjectName");
394: while ((projectName = validFreeProjectName(projectLocation,
395: formater, baseCount)) == null)
396: baseCount++;
397: }
398:
399: projectNameTextField.setText(projectName);
400: projectNameTextField.selectAll();
401: }
402:
403: // Variables declaration - do not modify//GEN-BEGIN:variables
404: private javax.swing.JButton Button;
405: private javax.swing.JLabel createdFolderLabel;
406: private javax.swing.JTextField createdFolderTextField;
407: private javax.swing.JLabel projectLocationLabel;
408: private javax.swing.JTextField projectLocationTextField;
409: private javax.swing.JLabel projectNameLabel;
410: protected javax.swing.JTextField projectNameTextField;
411:
412: // End of variables declaration//GEN-END:variables
413:
414: private static JFileChooser createChooser() {
415: JFileChooser chooser = new JFileChooser();
416: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
417: chooser.setAcceptAllFileFilterUsed(false);
418:
419: return chooser;
420: }
421:
422: private String validFreeProjectName(final File parentFolder,
423: final String formater, final int index) {
424: String name = MessageFormat.format(formater,
425: new Object[] { new Integer(index) });
426: File file = new File(parentFolder, name);
427: return file.exists() ? null : name;
428: }
429:
430: // Implementation of DocumentListener --------------------------------------
431: public void changedUpdate(DocumentEvent e) {
432: updateTexts(e);
433: }
434:
435: public void insertUpdate(DocumentEvent e) {
436: updateTexts(e);
437: }
438:
439: public void removeUpdate(DocumentEvent e) {
440: updateTexts(e);
441: }
442:
443: // End if implementation of DocumentListener -------------------------------
444:
445: /** Handles changes in the project name and project directory
446: */
447: private void updateTexts(DocumentEvent e) {
448: Document doc = e.getDocument();
449: if (doc == projectNameTextField.getDocument()
450: || doc == projectLocationTextField.getDocument()) {
451: // Change in the project name
452: String projectName = projectNameTextField.getText();
453: String projectFolder = projectLocationTextField.getText();
454: String projFolderPath = FileUtil.normalizeFile(
455: new File(projectFolder)).getAbsolutePath();
456: if (projFolderPath.endsWith(File.separator)) {
457: createdFolderTextField.setText(projFolderPath
458: + projectName);
459: } else {
460: createdFolderTextField.setText(projFolderPath
461: + File.separator + projectName);
462: }
463: }
464: panel.fireChangeEvent(); // Notify that the panel changed
465: }
466:
467: private String getCreatedFolderPath() {
468: StringBuffer folder = new StringBuffer(projectLocationTextField
469: .getText().trim());
470: if (!projectLocationTextField.getText()
471: .endsWith(File.separator))
472: folder.append(File.separatorChar);
473: folder.append(projectNameTextField.getText().trim());
474:
475: return folder.toString();
476: }
477:
478: static File getCanonicalFile(File file) {
479: try {
480: return file.getCanonicalFile();
481: } catch (IOException e) {
482: return null;
483: }
484: }
485:
486: }
487:
488: //TODO implement check for project folder name and location
|