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.java.editor.imports;
043:
044: import java.awt.BorderLayout;
045: import java.awt.Component;
046: import java.awt.Dimension;
047: import java.awt.Font;
048: import java.awt.GridBagConstraints;
049: import java.awt.GridBagLayout;
050: import java.awt.Insets;
051: import java.awt.Rectangle;
052: import java.awt.event.ActionEvent;
053: import java.awt.event.FocusEvent;
054: import java.awt.event.FocusListener;
055: import java.awt.event.KeyEvent;
056: import javax.swing.AbstractAction;
057: import javax.swing.Icon;
058: import javax.swing.InputMap;
059: import javax.swing.JCheckBox;
060: import javax.swing.JComboBox;
061: import javax.swing.JLabel;
062: import javax.swing.JList;
063: import javax.swing.KeyStroke;
064: import javax.swing.ListCellRenderer;
065: import javax.swing.UIManager;
066: import org.openide.awt.Mnemonics;
067: import org.openide.util.NbBundle;
068:
069: /**
070: * JTable with custom renderer, so second column looks editable (JComboBox).
071: * Second column also has CellEditor (also a JComboBox).
072: *
073: * @author eakle, Martin Roskanin
074: */
075: public class FixDuplicateImportStmts extends javax.swing.JPanel {
076: private JComboBox[] combos;
077: private JCheckBox checkUnusedImports;
078:
079: public FixDuplicateImportStmts() {
080: initComponents();
081: }
082:
083: public void initPanel(String[] simpleNames, String[][] choices,
084: Icon[][] icons, String[] defaults,
085: boolean removeUnusedImports) {
086: initComponentsMore(simpleNames, choices, icons, defaults,
087: removeUnusedImports);
088: setAccessible();
089: }
090:
091: private void initComponentsMore(String simpleNames[],
092: String choices[][], Icon[][] icons, String defaults[],
093: boolean removeUnusedImports) {
094: contentPanel.setLayout(new GridBagLayout());
095: contentPanel.setBackground(UIManager
096: .getColor("Table.background")); //NOI18N
097: jScrollPane1
098: .setBorder(UIManager.getBorder("ScrollPane.border")); //NOI18N
099: jScrollPane1.getVerticalScrollBar().setUnitIncrement(
100: new JLabel("X").getPreferredSize().height);
101: jScrollPane1.getVerticalScrollBar().setBlockIncrement(
102: new JLabel("X").getPreferredSize().height * 10);
103:
104: if (choices.length > 0) {
105:
106: int row = 0;
107:
108: combos = new JComboBox[choices.length];
109:
110: Font monoSpaced = new Font("Monospaced", Font.PLAIN,
111: new JLabel().getFont().getSize());
112: FocusListener focusListener = new FocusListener() {
113: public void focusGained(FocusEvent e) {
114: Component c = e.getComponent();
115: Rectangle r = c.getBounds();
116: contentPanel.scrollRectToVisible(r);
117: }
118:
119: public void focusLost(FocusEvent arg0) {
120: }
121: };
122: for (int i = 0; i < choices.length; i++) {
123: combos[i] = createComboBox(choices[i], defaults[i],
124: icons[i], monoSpaced, focusListener);
125:
126: JLabel lblSimpleName = new JLabel(simpleNames[i]);
127: lblSimpleName.setOpaque(false);
128: lblSimpleName.setFont(monoSpaced);
129: lblSimpleName.setLabelFor(combos[i]);
130:
131: contentPanel.add(lblSimpleName, new GridBagConstraints(
132: 0, row, 1, 1, 0.0, 0.0,
133: GridBagConstraints.WEST,
134: GridBagConstraints.NONE,
135: new Insets(3, 5, 2, 5), 0, 0));
136: contentPanel.add(combos[i], new GridBagConstraints(1,
137: row++, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
138: GridBagConstraints.HORIZONTAL, new Insets(3, 5,
139: 2, 5), 0, 0));
140: }
141:
142: contentPanel.add(new JLabel(), new GridBagConstraints(2,
143: row, 2, 1, 0.0, 1.0, GridBagConstraints.CENTER,
144: GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0,
145: 0));
146:
147: Dimension d = contentPanel.getPreferredSize();
148: d.height = getRowHeight() * Math.min(combos.length, 6);
149: jScrollPane1.getViewport().setPreferredSize(d);
150: } else {
151: contentPanel.add(new JLabel(
152: getBundleString("FixDupImportStmts_NothingToFix")),
153: new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
154: GridBagConstraints.CENTER,
155: GridBagConstraints.NONE, new Insets(20, 20,
156: 20, 20), 0, 0));
157: }
158:
159: // load localized text into widgets:
160: lblTitle.setText(getBundleString("FixDupImportStmts_IntroLbl")); //NOI18N
161: lblHeader.setText(getBundleString("FixDupImportStmts_Header")); //NOI18N
162:
163: checkUnusedImports = new JCheckBox();
164: Mnemonics.setLocalizedText(checkUnusedImports,
165: getBundleString("FixDupImportStmts_UnusedImports")); //NOI18N
166: bottomPanel.add(checkUnusedImports, BorderLayout.WEST);
167: checkUnusedImports.setEnabled(true);
168: checkUnusedImports.setSelected(removeUnusedImports);
169: }
170:
171: private JComboBox createComboBox(String[] choices,
172: String defaultValue, Icon[] icons, Font font,
173: FocusListener listener) {
174: JComboBox combo = new JComboBox(choices);
175: combo.setSelectedItem(defaultValue);
176: combo.getAccessibleContext().setAccessibleDescription(
177: getBundleString("FixDupImportStmts_Combo_ACSD")); //NOI18N
178: combo.getAccessibleContext().setAccessibleName(
179: getBundleString("FixDupImportStmts_Combo_Name_ACSD")); //NOI18N
180: combo.setOpaque(false);
181: combo.setFont(font);
182: combo.addFocusListener(listener);
183: combo.setEnabled(choices.length > 1);
184: combo.setRenderer(new DelegatingRenderer(combo.getRenderer(),
185: choices, icons));
186: InputMap inputMap = combo.getInputMap(JComboBox.WHEN_FOCUSED);
187: inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0),
188: "showPopup"); //NOI18N
189: combo.getActionMap().put("showPopup", new TogglePopupAction()); //NOI18N
190: return combo;
191: }
192:
193: private int getRowHeight() {
194: return combos.length == 0 ? 0
195: : combos[0].getPreferredSize().height + 6;
196: }
197:
198: private static String getBundleString(String s) {
199: return NbBundle.getMessage(FixDuplicateImportStmts.class, s);
200: }
201:
202: private void setAccessible() {
203: getAccessibleContext().setAccessibleDescription(
204: getBundleString("FixDupImportStmts_IntroLbl")); // NOI18N
205: checkUnusedImports
206: .getAccessibleContext()
207: .setAccessibleDescription(
208: getBundleString("FixDupImportStmts_checkUnusedImports_a11y")); // NOI18N
209: }
210:
211: public String[] getSelections() {
212: String[] res = new String[null == combos ? 0 : combos.length];
213: for (int i = 0; i < res.length; i++) {
214: res[i] = combos[i].getSelectedItem().toString();
215: }
216: return res;
217: }
218:
219: public boolean getRemoveUnusedImports() {
220: return checkUnusedImports.isSelected();
221: }
222:
223: /** This method is called from within the constructor to
224: * initialize the form.
225: * WARNING: Do NOT modify this code. The content of this method is
226: * always regenerated by the Form Editor.
227: */
228: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
229: private void initComponents() {
230: java.awt.GridBagConstraints gridBagConstraints;
231:
232: lblTitle = new javax.swing.JLabel();
233: jScrollPane1 = new javax.swing.JScrollPane();
234: contentPanel = new javax.swing.JPanel();
235: bottomPanel = new javax.swing.JPanel();
236: lblHeader = new javax.swing.JLabel();
237:
238: setBorder(javax.swing.BorderFactory.createEmptyBorder(12, 12,
239: 12, 12));
240: setPreferredSize(null);
241: setLayout(new java.awt.GridBagLayout());
242:
243: lblTitle
244: .setText("~Select the fully qualified name to use in the import statement.");
245: gridBagConstraints = new java.awt.GridBagConstraints();
246: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
247: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
248: gridBagConstraints.weightx = 0.1;
249: gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 0);
250: add(lblTitle, gridBagConstraints);
251:
252: jScrollPane1.setBorder(null);
253:
254: contentPanel.setLayout(new java.awt.GridBagLayout());
255: jScrollPane1.setViewportView(contentPanel);
256:
257: gridBagConstraints = new java.awt.GridBagConstraints();
258: gridBagConstraints.gridx = 0;
259: gridBagConstraints.gridy = 2;
260: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
261: gridBagConstraints.weightx = 1.0;
262: gridBagConstraints.weighty = 1.0;
263: add(jScrollPane1, gridBagConstraints);
264:
265: bottomPanel.setLayout(new java.awt.BorderLayout());
266: gridBagConstraints = new java.awt.GridBagConstraints();
267: gridBagConstraints.gridx = 0;
268: gridBagConstraints.gridy = 3;
269: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
270: gridBagConstraints.weightx = 1.0;
271: add(bottomPanel, gridBagConstraints);
272:
273: lblHeader.setText("~Import Statements:");
274: gridBagConstraints = new java.awt.GridBagConstraints();
275: gridBagConstraints.gridx = 0;
276: gridBagConstraints.gridy = 1;
277: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
278: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
279: gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 0);
280: add(lblHeader, gridBagConstraints);
281: }// </editor-fold>//GEN-END:initComponents
282:
283: // Variables declaration - do not modify//GEN-BEGIN:variables
284: private javax.swing.JPanel bottomPanel;
285: private javax.swing.JPanel contentPanel;
286: private javax.swing.JScrollPane jScrollPane1;
287: private javax.swing.JLabel lblHeader;
288: private javax.swing.JLabel lblTitle;
289:
290: // End of variables declaration//GEN-END:variables
291:
292: private static class DelegatingRenderer implements ListCellRenderer {
293: private ListCellRenderer orig;
294: private Icon[] icons;
295: private String[] values;
296:
297: public DelegatingRenderer(ListCellRenderer orig,
298: String[] values, Icon[] icons) {
299: this .orig = orig;
300: this .icons = icons;
301: this .values = values;
302: }
303:
304: public Component getListCellRendererComponent(JList list,
305: Object value, int index, boolean isSelected,
306: boolean cellHasFocus) {
307: Component res = orig.getListCellRendererComponent(list,
308: value, index, isSelected, cellHasFocus);
309: if (res instanceof JLabel && null != icons) {
310: for (int i = 0; i < values.length; i++) {
311: if (values[i].equals(value)) {
312: ((JLabel) res).setIcon(icons[i]);
313: break;
314: }
315: }
316: }
317: return res;
318: }
319: }
320:
321: private static class TogglePopupAction extends AbstractAction {
322: public void actionPerformed(ActionEvent e) {
323: if (e.getSource() instanceof JComboBox) {
324: JComboBox combo = (JComboBox) e.getSource();
325: combo.setPopupVisible(!combo.isPopupVisible());
326: }
327: }
328: }
329: }
|