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