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.beaninfo.editors;
043:
044: import java.awt.Component;
045: import java.awt.Dimension;
046: import java.awt.event.ActionEvent;
047: import java.awt.event.ActionListener;
048: import java.awt.event.KeyAdapter;
049: import java.awt.event.KeyEvent;
050: import java.util.Vector;
051: import java.util.ResourceBundle;
052:
053: import javax.swing.*;
054: import javax.swing.border.*;
055: import org.openide.awt.Mnemonics;
056:
057: //import org.openide.util.HelpCtx;
058: import org.openide.util.NbBundle;
059:
060: /** A custom editor for array of Strings.
061: *
062: * @author Ian Formanek
063: */
064: public class StringArrayCustomEditor extends javax.swing.JPanel {
065: private Vector<String> itemsVector;
066: private StringArrayCustomizable editor;
067:
068: static final long serialVersionUID = -4347656479280614636L;
069:
070: /** Initializes the Form */
071: public StringArrayCustomEditor(StringArrayCustomizable sac) {
072: editor = sac;
073: itemsVector = new Vector<String>();
074: String[] array = editor.getStringArray();
075: if (array != null)
076: for (int i = 0; i < array.length; i++)
077: itemsVector.addElement(array[i]);
078: initComponents();
079: itemList.setCellRenderer(new EmptyStringListCellRenderer());
080: itemList.setListData(itemsVector);
081: itemList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
082:
083: setBorder(new javax.swing.border.EmptyBorder(
084: new java.awt.Insets(16, 8, 8, 0)));
085: buttonsPanel.setBorder(new javax.swing.border.EmptyBorder(
086: new java.awt.Insets(0, 5, 5, 5)));
087:
088: Mnemonics.setLocalizedText(itemLabel, NbBundle.getMessage(
089: StringArrayCustomEditor.class, "CTL_Item")); //NOI18N
090: Mnemonics.setLocalizedText(itemListLabel, NbBundle.getMessage(
091: StringArrayCustomEditor.class, "CTL_ItemList")); //NOI18N
092: Mnemonics.setLocalizedText(addButton, NbBundle.getMessage(
093: StringArrayCustomEditor.class,
094: "CTL_Add_StringArrayCustomEditor")); //NOI18N
095: Mnemonics.setLocalizedText(changeButton, NbBundle.getMessage(
096: StringArrayCustomEditor.class,
097: "CTL_Change_StringArrayCustomEditor")); //NOI18N
098: Mnemonics.setLocalizedText(removeButton, NbBundle.getMessage(
099: StringArrayCustomEditor.class, "CTL_Remove")); //NOI18N
100: Mnemonics.setLocalizedText(moveUpButton, NbBundle.getMessage(
101: StringArrayCustomEditor.class, "CTL_MoveUp")); //NOI18N
102: Mnemonics.setLocalizedText(moveDownButton, NbBundle.getMessage(
103: StringArrayCustomEditor.class, "CTL_MoveDown")); //NOI18N
104:
105: getAccessibleContext().setAccessibleDescription(
106: NbBundle.getMessage(StringArrayCustomEditor.class,
107: "ACSD_StringArrayCustomEditor")); //NOI18N
108: itemField.getAccessibleContext().setAccessibleDescription(
109: NbBundle.getMessage(StringArrayCustomEditor.class,
110: "ACSD_CTL_Item")); //NOI18N
111: itemList.getAccessibleContext().setAccessibleDescription(
112: NbBundle.getMessage(StringArrayCustomEditor.class,
113: "ACSD_CTL_ItemList")); //NOI18N
114: addButton.getAccessibleContext().setAccessibleDescription(
115: NbBundle.getMessage(StringArrayCustomEditor.class,
116: "ACSD_CTL_Add_StringArrayCustomEditor")); //NOI18N
117: changeButton.getAccessibleContext().setAccessibleDescription(
118: NbBundle.getMessage(StringArrayCustomEditor.class,
119: "ACSD_CTL_Change_StringArrayCustomEditor")); //NOI18N
120: removeButton.getAccessibleContext().setAccessibleDescription(
121: NbBundle.getMessage(StringArrayCustomEditor.class,
122: "ACSD_CTL_Remove")); //NOI18N
123: moveUpButton.getAccessibleContext().setAccessibleDescription(
124: NbBundle.getMessage(StringArrayCustomEditor.class,
125: "ACSD_CTL_MoveUp")); //NOI18N
126: moveDownButton.getAccessibleContext().setAccessibleDescription(
127: NbBundle.getMessage(StringArrayCustomEditor.class,
128: "ACSD_CTL_MoveDown")); //NOI18N
129:
130: updateButtons();
131: itemField.addKeyListener(new KeyAdapter() {
132: public void keyReleased(KeyEvent event) {
133: boolean containsCurrent = containsCurrent();
134: String txt = itemField.getText().trim();
135: boolean en = itemField.isEnabled() && txt.length() > 0
136: && !containsCurrent;
137: addButton.setEnabled(en);
138: changeButton.setEnabled(en
139: && itemList.getSelectedIndex() != -1);
140: if (containsCurrent) {
141: itemList.setSelectedIndex(idxOfCurrent());
142: }
143: }
144: });
145: itemField.addActionListener(new ActionListener() {
146: public void actionPerformed(ActionEvent ae) {
147: if (addButton.isEnabled()) {
148: addButtonActionPerformed(ae);
149: }
150: }
151: });
152: addButton.setEnabled(false);
153: changeButton.setEnabled(false);
154: // HelpCtx.setHelpIDString (this, StringArrayCustomEditor.class.getName ());
155: setMinimumSize(new Dimension(200, 400));
156: }
157:
158: /** Determine if the text of the text field matches an item in the
159: * list */
160: private boolean containsCurrent() {
161: return idxOfCurrent() != -1;
162: }
163:
164: private int idxOfCurrent() {
165: String txt = itemField.getText().trim();
166: if (txt.length() > 0) {
167: int max = itemList.getModel().getSize();
168: for (int i = 0; i < max; i++) {
169: if (txt.equals(itemList.getModel().getElementAt(i)))
170: return i;
171: }
172: }
173: return -1;
174: }
175:
176: /** This method is called from within the constructor to
177: * initialize the form.
178: * WARNING: Do NOT modify this code. The content of this method is
179: * always regenerated by the FormEditor.
180: */
181: private void initComponents() {//GEN-BEGIN:initComponents
182: editPanel = new javax.swing.JPanel();
183: itemListScroll = new javax.swing.JScrollPane();
184: itemList = new javax.swing.JList();
185: itemLabel = new javax.swing.JLabel();
186: itemField = new javax.swing.JTextField();
187: itemListLabel = new javax.swing.JLabel();
188: buttonsPanel = new javax.swing.JPanel();
189: addButton = new javax.swing.JButton();
190: changeButton = new javax.swing.JButton();
191: removeButton = new javax.swing.JButton();
192: jSeparator1 = new javax.swing.JSeparator();
193: moveUpButton = new javax.swing.JButton();
194: moveDownButton = new javax.swing.JButton();
195: paddingPanel = new javax.swing.JPanel();
196:
197: setLayout(new java.awt.BorderLayout());
198:
199: editPanel.setLayout(new java.awt.GridBagLayout());
200: java.awt.GridBagConstraints gridBagConstraints2;
201:
202: itemList
203: .addListSelectionListener(new javax.swing.event.ListSelectionListener() {
204: public void valueChanged(
205: javax.swing.event.ListSelectionEvent evt) {
206: itemListValueChanged(evt);
207: }
208: });
209:
210: itemListScroll.setViewportView(itemList);
211:
212: gridBagConstraints2 = new java.awt.GridBagConstraints();
213: gridBagConstraints2.gridx = 0;
214: gridBagConstraints2.gridy = 2;
215: gridBagConstraints2.gridwidth = 2;
216: gridBagConstraints2.fill = java.awt.GridBagConstraints.BOTH;
217: gridBagConstraints2.weightx = 1.0;
218: gridBagConstraints2.weighty = 1.0;
219: editPanel.add(itemListScroll, gridBagConstraints2);
220:
221: itemLabel.setText("item");
222: itemLabel.setLabelFor(itemField);
223: gridBagConstraints2 = new java.awt.GridBagConstraints();
224: gridBagConstraints2.insets = new java.awt.Insets(0, 0, 11, 12);
225: gridBagConstraints2.anchor = java.awt.GridBagConstraints.WEST;
226: editPanel.add(itemLabel, gridBagConstraints2);
227:
228: gridBagConstraints2 = new java.awt.GridBagConstraints();
229: gridBagConstraints2.fill = java.awt.GridBagConstraints.HORIZONTAL;
230: gridBagConstraints2.insets = new java.awt.Insets(0, 0, 11, 0);
231: editPanel.add(itemField, gridBagConstraints2);
232:
233: itemListLabel.setText("jLabel1");
234: itemListLabel.setLabelFor(itemList);
235: gridBagConstraints2 = new java.awt.GridBagConstraints();
236: gridBagConstraints2.gridx = 0;
237: gridBagConstraints2.gridy = 1;
238: gridBagConstraints2.gridwidth = 2;
239: gridBagConstraints2.insets = new java.awt.Insets(0, 0, 2, 0);
240: gridBagConstraints2.anchor = java.awt.GridBagConstraints.WEST;
241: editPanel.add(itemListLabel, gridBagConstraints2);
242:
243: add(editPanel, java.awt.BorderLayout.CENTER);
244:
245: buttonsPanel.setLayout(new java.awt.GridBagLayout());
246: java.awt.GridBagConstraints gridBagConstraints1;
247:
248: addButton
249: .addActionListener(new java.awt.event.ActionListener() {
250: public void actionPerformed(
251: java.awt.event.ActionEvent evt) {
252: addButtonActionPerformed(evt);
253: }
254: });
255:
256: gridBagConstraints1 = new java.awt.GridBagConstraints();
257: gridBagConstraints1.gridwidth = java.awt.GridBagConstraints.REMAINDER;
258: gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
259: gridBagConstraints1.insets = new java.awt.Insets(0, 8, 0, 8);
260: gridBagConstraints1.weightx = 1.0;
261: buttonsPanel.add(addButton, gridBagConstraints1);
262:
263: changeButton
264: .addActionListener(new java.awt.event.ActionListener() {
265: public void actionPerformed(
266: java.awt.event.ActionEvent evt) {
267: changeButtonActionPerformed(evt);
268: }
269: });
270:
271: gridBagConstraints1 = new java.awt.GridBagConstraints();
272: gridBagConstraints1.gridwidth = java.awt.GridBagConstraints.REMAINDER;
273: gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
274: gridBagConstraints1.insets = new java.awt.Insets(8, 8, 0, 8);
275: gridBagConstraints1.weightx = 1.0;
276: buttonsPanel.add(changeButton, gridBagConstraints1);
277:
278: removeButton
279: .addActionListener(new java.awt.event.ActionListener() {
280: public void actionPerformed(
281: java.awt.event.ActionEvent evt) {
282: removeButtonActionPerformed(evt);
283: }
284: });
285:
286: gridBagConstraints1 = new java.awt.GridBagConstraints();
287: gridBagConstraints1.gridwidth = java.awt.GridBagConstraints.REMAINDER;
288: gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
289: gridBagConstraints1.insets = new java.awt.Insets(8, 8, 8, 8);
290: gridBagConstraints1.weightx = 1.0;
291: buttonsPanel.add(removeButton, gridBagConstraints1);
292:
293: gridBagConstraints1 = new java.awt.GridBagConstraints();
294: gridBagConstraints1.gridwidth = java.awt.GridBagConstraints.REMAINDER;
295: gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
296: gridBagConstraints1.insets = new java.awt.Insets(0, 4, 0, 4);
297: buttonsPanel.add(jSeparator1, gridBagConstraints1);
298:
299: moveUpButton.setEnabled(false);
300: moveUpButton
301: .addActionListener(new java.awt.event.ActionListener() {
302: public void actionPerformed(
303: java.awt.event.ActionEvent evt) {
304: moveUpButtonActionPerformed(evt);
305: }
306: });
307:
308: gridBagConstraints1 = new java.awt.GridBagConstraints();
309: gridBagConstraints1.gridwidth = java.awt.GridBagConstraints.REMAINDER;
310: gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
311: gridBagConstraints1.insets = new java.awt.Insets(8, 8, 0, 8);
312: gridBagConstraints1.weightx = 1.0;
313: buttonsPanel.add(moveUpButton, gridBagConstraints1);
314:
315: moveDownButton.setEnabled(false);
316: moveDownButton
317: .addActionListener(new java.awt.event.ActionListener() {
318: public void actionPerformed(
319: java.awt.event.ActionEvent evt) {
320: moveDownButtonActionPerformed(evt);
321: }
322: });
323:
324: gridBagConstraints1 = new java.awt.GridBagConstraints();
325: gridBagConstraints1.gridwidth = java.awt.GridBagConstraints.REMAINDER;
326: gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
327: gridBagConstraints1.insets = new java.awt.Insets(8, 8, 0, 8);
328: gridBagConstraints1.weightx = 1.0;
329: buttonsPanel.add(moveDownButton, gridBagConstraints1);
330:
331: gridBagConstraints1 = new java.awt.GridBagConstraints();
332: gridBagConstraints1.weighty = 1.0;
333: buttonsPanel.add(paddingPanel, gridBagConstraints1);
334:
335: add(buttonsPanel, java.awt.BorderLayout.EAST);
336:
337: }//GEN-END:initComponents
338:
339: private void changeButtonActionPerformed(
340: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changeButtonActionPerformed
341: int sel = itemList.getSelectedIndex();
342: String s = itemsVector.elementAt(sel);
343: itemsVector.removeElementAt(sel);
344: itemsVector.insertElementAt(itemField.getText(), sel);
345: itemList.setListData(itemsVector);
346: itemList.setSelectedIndex(sel);
347: itemList.repaint();
348: updateValue();
349: }//GEN-LAST:event_changeButtonActionPerformed
350:
351: private void moveDownButtonActionPerformed(
352: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_moveDownButtonActionPerformed
353: int sel = itemList.getSelectedIndex();
354: String s = itemsVector.elementAt(sel);
355: itemsVector.removeElementAt(sel);
356: itemsVector.insertElementAt(s, sel + 1);
357: itemList.setListData(itemsVector);
358: itemList.setSelectedIndex(sel + 1);
359: itemList.repaint();
360: updateValue();
361: }//GEN-LAST:event_moveDownButtonActionPerformed
362:
363: private void moveUpButtonActionPerformed(
364: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_moveUpButtonActionPerformed
365: int sel = itemList.getSelectedIndex();
366: String s = itemsVector.elementAt(sel);
367: itemsVector.removeElementAt(sel);
368: itemsVector.insertElementAt(s, sel - 1);
369: itemList.setListData(itemsVector);
370: itemList.setSelectedIndex(sel - 1);
371: itemList.repaint();
372: updateValue();
373: }//GEN-LAST:event_moveUpButtonActionPerformed
374:
375: private void removeButtonActionPerformed(
376: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed
377: // Add your handling code here:
378: int currentIndex = itemList.getSelectedIndex();
379: itemsVector.removeElementAt(currentIndex);
380: itemList.setListData(itemsVector);
381:
382: // set new selection
383: if (itemsVector.size() != 0) {
384: if (currentIndex >= itemsVector.size())
385: currentIndex = itemsVector.size() - 1;
386: itemList.setSelectedIndex(currentIndex);
387: }
388:
389: itemList.repaint();
390:
391: updateValue();
392: }//GEN-LAST:event_removeButtonActionPerformed
393:
394: private void itemListValueChanged(
395: javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_itemListValueChanged
396: // Add your handling code here:
397: updateButtons();
398: int sel = itemList.getSelectedIndex();
399: if (sel != -1) {
400: itemField.setText(itemsVector.elementAt(sel));
401: }
402: }//GEN-LAST:event_itemListValueChanged
403:
404: private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
405: // Add your handling code here:
406: itemsVector.addElement(itemField.getText());
407: itemList.setListData(itemsVector);
408: itemList.setSelectedIndex(itemsVector.size() - 1);
409: itemList.repaint();
410: updateValue();
411: }//GEN-LAST:event_addButtonActionPerformed
412:
413: public void setEnabled(boolean val) {
414: Component[] c = getComponents();
415: super .setEnabled(val);
416: setChildrenEnabled(this , val);
417: }
418:
419: private void setChildrenEnabled(JPanel parent, boolean val) {
420: Component[] c = parent.getComponents();
421: for (int i = 0; i < c.length; i++) {
422: c[i].setEnabled(val);
423: if (c[i] instanceof JPanel) {
424: setChildrenEnabled((JPanel) c[i], val);
425: }
426: }
427: }
428:
429: private void updateButtons() {
430: int sel = itemList.getSelectedIndex();
431: boolean enVal = isEnabled();
432: if (sel == -1) {
433: removeButton.setEnabled(false);
434: moveUpButton.setEnabled(false);
435: moveDownButton.setEnabled(false);
436: changeButton.setEnabled(false);
437: } else {
438: removeButton.setEnabled(enVal && true);
439: moveUpButton.setEnabled(enVal && (sel != 0));
440: moveDownButton.setEnabled(enVal
441: && (sel != itemsVector.size() - 1));
442: changeButton.setEnabled(enVal && true);
443: }
444: itemField.setEnabled(enVal);
445: // #62803: String[] editor keeps text in the textfield after removing all items
446: boolean containsCurrent = containsCurrent();
447: String txt = itemField.getText().trim();
448: boolean en = itemField.isEnabled() && txt.length() > 0
449: && !containsCurrent;
450: addButton.setEnabled(en);
451: }
452:
453: private void updateValue() {
454: String[] value = new String[itemsVector.size()];
455: itemsVector.copyInto(value);
456: editor.setStringArray(value);
457: }
458:
459: // Variables declaration - do not modify//GEN-BEGIN:variables
460: private javax.swing.JPanel editPanel;
461: private javax.swing.JScrollPane itemListScroll;
462: private javax.swing.JList itemList;
463: private javax.swing.JLabel itemLabel;
464: private javax.swing.JTextField itemField;
465: private javax.swing.JLabel itemListLabel;
466: private javax.swing.JPanel buttonsPanel;
467: private javax.swing.JButton addButton;
468: private javax.swing.JButton changeButton;
469: private javax.swing.JButton removeButton;
470: private javax.swing.JSeparator jSeparator1;
471: private javax.swing.JButton moveUpButton;
472: private javax.swing.JButton moveDownButton;
473: private javax.swing.JPanel paddingPanel;
474:
475: // End of variables declaration//GEN-END:variables
476:
477: static class EmptyStringListCellRenderer extends JLabel implements
478: ListCellRenderer {
479:
480: protected static Border hasFocusBorder;
481: protected static Border noFocusBorder;
482:
483: static {
484: hasFocusBorder = new LineBorder(UIManager
485: .getColor("List.focusCellHighlight")); // NOI18N
486: noFocusBorder = new EmptyBorder(1, 1, 1, 1);
487: }
488:
489: static final long serialVersionUID = 487512296465844339L;
490:
491: /** Creates a new NodeListCellRenderer */
492: public EmptyStringListCellRenderer() {
493: setOpaque(true);
494: setBorder(noFocusBorder);
495: }
496:
497: /** This is the only method defined by ListCellRenderer. We just
498: * reconfigure the Jlabel each time we're called.
499: */
500: public java.awt.Component getListCellRendererComponent(
501: JList list, Object value, // value to display
502: int index, // cell index
503: boolean isSelected, // is the cell selected
504: boolean cellHasFocus) // the list and the cell have the focus
505: {
506: if (!(value instanceof String))
507: return this ;
508: String text = (String) value;
509: if ("".equals(text))
510: text = NbBundle.getMessage(
511: StringArrayCustomEditor.class, "CTL_Empty");
512:
513: setText(text);
514: if (isSelected) {
515: setBackground(UIManager
516: .getColor("List.selectionBackground")); // NOI18N
517: setForeground(UIManager
518: .getColor("List.selectionForeground")); // NOI18N
519: } else {
520: setBackground(list.getBackground());
521: setForeground(list.getForeground());
522: }
523:
524: setBorder(cellHasFocus ? hasFocusBorder : noFocusBorder);
525:
526: return this;
527: }
528: }
529: }
|