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.visualweb.insync.faces.refactoring;
043:
044: import java.awt.Component;
045: import java.awt.event.ActionEvent;
046: import java.awt.event.ActionListener;
047: import java.text.Collator;
048: import java.util.Comparator;
049: import java.util.Enumeration;
050: import java.util.LinkedHashSet;
051: import java.util.Set;
052: import java.util.TreeSet;
053: import javax.swing.DefaultComboBoxModel;
054: import javax.swing.JLabel;
055: import javax.swing.JList;
056: import javax.swing.JPanel;
057: import javax.swing.ListCellRenderer;
058: import javax.swing.event.ChangeListener;
059: import javax.swing.plaf.UIResource;
060: import org.netbeans.api.project.FileOwnerQuery;
061: import org.netbeans.api.project.Project;
062: import org.netbeans.api.project.ProjectInformation;
063: import org.netbeans.api.project.ProjectUtils;
064: import org.netbeans.api.project.ui.OpenProjects;
065: import org.netbeans.modules.refactoring.spi.ui.CustomRefactoringPanel;
066: import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectUtils;
067: import org.openide.filesystems.FileObject;
068: import org.openide.filesystems.FileUtil;
069:
070: /**
071: * Asks where to move a Page to.
072: * @author Jan Becicka, Jesse Glick
073: */
074: public class FacesMovePanel extends JPanel implements ActionListener,
075: CustomRefactoringPanel {
076:
077: private static final ListCellRenderer PROJECT_CELL_RENDERER = new ProjectCellRenderer();
078: private static final ProjectByDisplayNameComparator PROJECT_BY_DISPLAY_NAME_COMPARATOR = new ProjectByDisplayNameComparator();
079:
080: private ChangeListener parent;
081: private Project project;
082: private FileObject webRootFolder;
083: private FileObject fo;
084:
085: public FacesMovePanel(final ChangeListener parent, String title,
086: FileObject f) {
087: this .parent = parent;
088: this .fo = f;
089:
090: initComponents();
091:
092: setCombosEnabled(true);
093: setName(title);
094:
095: projectsComboBox.setRenderer(PROJECT_CELL_RENDERER);
096: folderComboBox.setRenderer(new FolderRenderer());
097:
098: projectsComboBox.addActionListener(this );
099: folderComboBox.addActionListener(this );
100:
101: project = fo != null ? FileOwnerQuery.getOwner(fo)
102: : OpenProjects.getDefault().getOpenProjects()[0];
103: }
104:
105: private boolean initialized = false;
106:
107: public void initialize() {
108: if (initialized)
109: return;
110: //put initialization code here
111: initValues(fo);
112: initialized = true;
113: }
114:
115: public void initValues(FileObject preselectedFolder) {
116: Project openProjects[] = OpenProjects.getDefault()
117: .getOpenProjects();
118: Set<? super Project> webProjects = new TreeSet<Project>(
119: PROJECT_BY_DISPLAY_NAME_COMPARATOR);
120: for (Project project : openProjects) {
121: if (JsfProjectUtils.isJsfProject(project)) {
122: webProjects.add(project);
123: }
124: }
125:
126: DefaultComboBoxModel projectsModel = new DefaultComboBoxModel(
127: webProjects.toArray());
128: projectsComboBox.setModel(projectsModel);
129: projectsComboBox.setSelectedItem(project);
130:
131: updateRoot();
132: updateFolders();
133: if (preselectedFolder != null) {
134: folderComboBox.setSelectedItem(preselectedFolder);
135: }
136: // Determine the extension
137: }
138:
139: public void requestFocus() {
140: folderComboBox.requestFocus();
141: }
142:
143: public FileObject getWebRootFolder() {
144: return webRootFolder;
145: }
146:
147: public FileObject getTargeFolder() {
148: FileObject fileObject = (FileObject) folderComboBox
149: .getSelectedItem();
150: if (fileObject != null) {
151: return fileObject;
152: }
153: return null;
154: }
155:
156: private void fireChange() {
157: parent.stateChanged(null);
158: }
159:
160: /** This method is called from within the constructor to
161: * initialize the form.
162: * WARNING: Do NOT modify this code. The content of this method is
163: * always regenerated by the Form Editor.
164: */
165: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
166: private void initComponents() {
167: java.awt.GridBagConstraints gridBagConstraints;
168:
169: labelProject = new javax.swing.JLabel();
170: projectsComboBox = new javax.swing.JComboBox();
171: labelWebRoot = new javax.swing.JLabel();
172: webRootTextField = new javax.swing.JTextField();
173: labelFolder = new javax.swing.JLabel();
174: folderComboBox = new javax.swing.JComboBox();
175: bottomPanel = new javax.swing.JPanel();
176: labelHeadLine = new javax.swing.JLabel();
177: updateReferencesCheckBox = new javax.swing.JCheckBox();
178:
179: setLayout(new java.awt.GridBagLayout());
180:
181: labelProject.setLabelFor(projectsComboBox);
182: org.openide.awt.Mnemonics.setLocalizedText(labelProject,
183: org.openide.util.NbBundle.getMessage(
184: FacesMovePanel.class, "LBL_Project")); // NOI18N
185: gridBagConstraints = new java.awt.GridBagConstraints();
186: gridBagConstraints.gridx = 0;
187: gridBagConstraints.gridy = 1;
188: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
189: gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 0);
190: add(labelProject, gridBagConstraints);
191: gridBagConstraints = new java.awt.GridBagConstraints();
192: gridBagConstraints.gridx = 1;
193: gridBagConstraints.gridy = 1;
194: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
195: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
196: gridBagConstraints.weightx = 1.0;
197: gridBagConstraints.insets = new java.awt.Insets(0, 6, 6, 0);
198: add(projectsComboBox, gridBagConstraints);
199: java.util.ResourceBundle bundle = java.util.ResourceBundle
200: .getBundle("org/netbeans/modules/visualweb/insync/faces/refactoring/Bundle"); // NOI18N
201: projectsComboBox.getAccessibleContext()
202: .setAccessibleDescription(
203: bundle.getString("ACSD_projectsCombo")); // NOI18N
204:
205: org.openide.awt.Mnemonics.setLocalizedText(labelWebRoot,
206: org.openide.util.NbBundle.getMessage(
207: FacesMovePanel.class, "LBL_Location")); // NOI18N
208: gridBagConstraints = new java.awt.GridBagConstraints();
209: gridBagConstraints.gridx = 0;
210: gridBagConstraints.gridy = 2;
211: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
212: gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 0);
213: add(labelWebRoot, gridBagConstraints);
214:
215: webRootTextField.setEditable(false);
216: gridBagConstraints = new java.awt.GridBagConstraints();
217: gridBagConstraints.gridx = 1;
218: gridBagConstraints.gridy = 2;
219: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
220: gridBagConstraints.weightx = 1.0;
221: gridBagConstraints.insets = new java.awt.Insets(0, 6, 6, 0);
222: add(webRootTextField, gridBagConstraints);
223:
224: labelFolder.setLabelFor(folderComboBox);
225: org.openide.awt.Mnemonics.setLocalizedText(labelFolder,
226: org.openide.util.NbBundle.getMessage(
227: FacesMovePanel.class, "LBL_Folder")); // NOI18N
228: gridBagConstraints = new java.awt.GridBagConstraints();
229: gridBagConstraints.gridx = 0;
230: gridBagConstraints.gridy = 3;
231: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
232: gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 0);
233: add(labelFolder, gridBagConstraints);
234:
235: gridBagConstraints = new java.awt.GridBagConstraints();
236: gridBagConstraints.gridx = 1;
237: gridBagConstraints.gridy = 3;
238: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
239: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
240: gridBagConstraints.weightx = 1.0;
241: gridBagConstraints.insets = new java.awt.Insets(0, 6, 6, 0);
242: add(folderComboBox, gridBagConstraints);
243: gridBagConstraints = new java.awt.GridBagConstraints();
244: gridBagConstraints.gridx = 0;
245: gridBagConstraints.gridy = 4;
246: gridBagConstraints.gridwidth = 2;
247: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
248: gridBagConstraints.weightx = 1.0;
249: gridBagConstraints.weighty = 1.0;
250: add(bottomPanel, gridBagConstraints);
251:
252: labelHeadLine.setBorder(javax.swing.BorderFactory
253: .createEmptyBorder(1, 1, 6, 1));
254: gridBagConstraints = new java.awt.GridBagConstraints();
255: gridBagConstraints.gridx = 0;
256: gridBagConstraints.gridy = 0;
257: gridBagConstraints.gridwidth = 2;
258: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
259: add(labelHeadLine, gridBagConstraints);
260:
261: org.openide.awt.Mnemonics.setLocalizedText(
262: updateReferencesCheckBox, org.openide.util.NbBundle
263: .getBundle(FacesMovePanel.class).getString(
264: "LBL_MoveWithoutReferences")); // NOI18N
265: updateReferencesCheckBox.setBorder(javax.swing.BorderFactory
266: .createEmptyBorder(4, 4, 0, 4));
267: updateReferencesCheckBox.setMargin(new java.awt.Insets(2, 2, 0,
268: 2));
269: gridBagConstraints = new java.awt.GridBagConstraints();
270: gridBagConstraints.gridx = 0;
271: gridBagConstraints.gridy = 5;
272: gridBagConstraints.gridwidth = 2;
273: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
274: add(updateReferencesCheckBox, gridBagConstraints);
275: }// </editor-fold>//GEN-END:initComponents
276:
277: // Variables declaration - do not modify//GEN-BEGIN:variables
278: protected javax.swing.JPanel bottomPanel;
279: private javax.swing.JComboBox folderComboBox;
280: private javax.swing.JLabel labelFolder;
281: private javax.swing.JLabel labelHeadLine;
282: private javax.swing.JLabel labelProject;
283: private javax.swing.JLabel labelWebRoot;
284: private javax.swing.JComboBox projectsComboBox;
285: private javax.swing.JCheckBox updateReferencesCheckBox;
286: private javax.swing.JTextField webRootTextField;
287:
288: // End of variables declaration//GEN-END:variables
289:
290: // ActionListener implementation -------------------------------------------
291:
292: public void actionPerformed(ActionEvent e) {
293: if (projectsComboBox == e.getSource()) {
294: project = (Project) projectsComboBox.getSelectedItem();
295: updateRoot();
296: updateFolders();
297: fireChange();
298: } else if (folderComboBox == e.getSource()) {
299: fireChange();
300: }
301: }
302:
303: // Private methods ---------------------------------------------------------
304:
305: private void updateFolders() {
306: Set<FileObject> folders = new LinkedHashSet<FileObject>();
307: // Update folders under web folder
308: if (webRootFolder != null) {
309: folders.add(webRootFolder);
310: Enumeration<? extends FileObject> children = webRootFolder
311: .getChildren(true);
312: while (children.hasMoreElements()) {
313: FileObject child = children.nextElement();
314: // Only folders
315: if (child.isFolder()) {
316: // Not special folders
317: if (child.getNameExt().equalsIgnoreCase("META-INF")
318: || // NOI18N
319: child.getNameExt().equalsIgnoreCase(
320: "WEB-INF")) { // NOI18N
321: continue;
322: }
323: // Not children of special folders
324: String relativePath = FileUtil.getRelativePath(
325: webRootFolder, child);
326: if (relativePath != null) {
327: if (relativePath.startsWith("META-INF/") || // NOI18N
328: relativePath.startsWith("WEB-INF/")) { // NOI18N
329: continue;
330: }
331: }
332: folders.add(child);
333: }
334: }
335:
336: }
337: folderComboBox.setModel(new DefaultComboBoxModel(folders
338: .toArray(new FileObject[folders.size()])));
339: }
340:
341: void setCombosEnabled(boolean enabled) {
342: projectsComboBox.setEnabled(enabled);
343: folderComboBox.setEnabled(enabled);
344: updateReferencesCheckBox.setVisible(!enabled);
345: }
346:
347: public boolean isUpdateReferences() {
348: if (updateReferencesCheckBox.isVisible()
349: && updateReferencesCheckBox.isSelected())
350: return false;
351: return true;
352: }
353:
354: private void updateRoot() {
355: webRootTextField.setText("");
356: webRootFolder = null;
357: Project selectedProject = (Project) projectsComboBox
358: .getSelectedItem();
359: if (selectedProject != null) {
360: FileObject projectDirectory = selectedProject
361: .getProjectDirectory();
362: if (projectDirectory != null) {
363: webRootFolder = JsfProjectUtils
364: .getDocumentRoot(project);
365: if (webRootFolder != null) {
366: webRootTextField.setText(FileUtil.getRelativePath(
367: projectDirectory, webRootFolder));
368: }
369: }
370: }
371: }
372:
373: private abstract static class BaseCellRenderer extends JLabel
374: implements ListCellRenderer, UIResource {
375:
376: public BaseCellRenderer() {
377: setOpaque(true);
378: }
379:
380: // #89393: GTK needs name to render cell renderer "natively"
381: public String getName() {
382: String name = super .getName();
383: return name == null ? "ComboBox.renderer" : name; // NOI18N
384: }
385: }
386:
387: /** Projects combo renderer, used also in CopyClassPanel */
388: static class ProjectCellRenderer extends BaseCellRenderer {
389:
390: public Component getListCellRendererComponent(JList list,
391: Object value, int index, boolean isSelected,
392: boolean cellHasFocus) {
393:
394: // #89393: GTK needs name to render cell renderer "natively"
395: setName("ComboBox.listRenderer"); // NOI18N
396:
397: if (value != null) {
398: ProjectInformation pi = ProjectUtils
399: .getInformation((Project) value);
400: setText(pi.getDisplayName());
401: setIcon(pi.getIcon());
402: }
403:
404: if (isSelected) {
405: setBackground(list.getSelectionBackground());
406: setForeground(list.getSelectionForeground());
407: } else {
408: setBackground(list.getBackground());
409: setForeground(list.getForeground());
410: }
411:
412: return this ;
413: }
414: }
415:
416: class FolderRenderer extends BaseCellRenderer {
417:
418: public Component getListCellRendererComponent(JList list,
419: Object value, int index, boolean isSelected,
420: boolean cellHasFocus) {
421:
422: // #89393: GTK needs name to render cell renderer "natively"
423: setName("ComboBox.listRenderer"); // NOI18N
424:
425: FileObject folder = (FileObject) value;
426: if (webRootFolder != null) {
427: if (webRootFolder == folder) {
428: setText(".");
429: } else {
430: setText(FileUtil.getRelativePath(webRootFolder,
431: folder));
432: }
433: } else {
434: setText(folder.getPath());
435: }
436:
437: if (isSelected) {
438: setBackground(list.getSelectionBackground());
439: setForeground(list.getSelectionForeground());
440: } else {
441: setBackground(list.getBackground());
442: setForeground(list.getForeground());
443: }
444:
445: return this ;
446: }
447: }
448:
449: //Copy/pasted from OpenProjectList
450: //remove this code as soon as #68827 is fixed.
451: private static class ProjectByDisplayNameComparator implements
452: Comparator {
453:
454: private static Comparator COLLATOR = Collator.getInstance();
455:
456: public int compare(Object o1, Object o2) {
457:
458: if (!(o1 instanceof Project)) {
459: return 1;
460: }
461: if (!(o2 instanceof Project)) {
462: return -1;
463: }
464:
465: Project p1 = (Project) o1;
466: Project p2 = (Project) o2;
467:
468: return COLLATOR.compare(ProjectUtils.getInformation(p1)
469: .getDisplayName(), ProjectUtils.getInformation(p2)
470: .getDisplayName());
471: }
472: }
473:
474: public Component getComponent() {
475: return this;
476: }
477: }
|