KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > sun > share > configbean > customizers > data > DynamicPropertyPanel


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 /*
20  * DynamicPropertyPanel.java
21  *
22  * Created on January 29, 2004, 2:28 PM
23  */

24
25 package org.netbeans.modules.j2ee.sun.share.configbean.customizers.data;
26
27 import java.util.ArrayList JavaDoc;
28 import java.util.Collection JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Locale JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.ResourceBundle JavaDoc;
34 import java.util.SortedMap JavaDoc;
35 import java.util.regex.Pattern JavaDoc;
36 import java.text.MessageFormat JavaDoc;
37
38 import java.awt.GridBagConstraints JavaDoc;
39 import java.awt.Insets JavaDoc;
40 import java.awt.Dimension JavaDoc;
41 import java.awt.Window JavaDoc;
42 import java.awt.Container JavaDoc;
43 import java.awt.Component JavaDoc;
44 import java.awt.Rectangle JavaDoc;
45
46 import javax.swing.JPanel JavaDoc;
47 import javax.swing.JLabel JavaDoc;
48 import javax.swing.JComboBox JavaDoc;
49 import javax.swing.JCheckBox JavaDoc;
50 import javax.swing.JComponent JavaDoc;
51 import javax.swing.JTextField JavaDoc;
52 import javax.swing.DefaultComboBoxModel JavaDoc;
53
54 import org.netbeans.modules.j2ee.sun.share.Constants;
55 import org.netbeans.modules.j2ee.sun.share.configbean.ASDDVersion;
56 import org.netbeans.modules.j2ee.sun.share.configbean.Utils;
57 import org.netbeans.modules.j2ee.sun.share.configbean.customizers.common.GenericTableDialogPanelAccessor;
58 import org.netbeans.modules.j2ee.sun.share.configbean.customizers.common.ValidationSupport;
59 import org.netbeans.modules.j2ee.sun.share.configbean.customizers.webapp.LocaleMapping;
60 import org.netbeans.modules.j2ee.sun.share.CharsetMapping;
61
62 /**
63  *
64  * @author Peter Williams
65  */

66 public class DynamicPropertyPanel extends JPanel JavaDoc
67     implements GenericTableDialogPanelAccessor {
68     
69     // Panel state
70
private boolean isEditPopup; // <edit> versus <new>
71

72     // Data support
73
private PropertyList theList;
74     private List JavaDoc paramMappings;
75     private boolean hasDescription;
76     private boolean isEditable;
77     
78     // Visual Components
79
private JLabel JavaDoc nameRequiredMark;
80     private JLabel JavaDoc nameLabel;
81     private JLabel JavaDoc valueRequiredMark ;
82     private JLabel JavaDoc valueLabel;
83     private JComboBox JavaDoc propertiesCombo;
84     private JComponent JavaDoc customEditor;
85     private JTextField JavaDoc descriptionField;
86     
87     // Swappable components for custom editor
88
private JTextField JavaDoc customTextField;
89     private JComboBox JavaDoc customComboBox;
90     private JCheckBox JavaDoc customCheckBox;
91     private int normalizedHeight;
92     
93     // Data models
94
private DefaultComboBoxModel JavaDoc propertyListModel;
95     
96     // Field data storage
97
private String JavaDoc name;
98     private ParamMapping nameMapping;
99     private String JavaDoc value;
100     private String JavaDoc description;
101     
102     // Standard resource bundle to use for non-property list fields
103
private static final ResourceBundle JavaDoc localBundle = ResourceBundle.getBundle(
104         "org.netbeans.modules.j2ee.sun.share.configbean.customizers.common.Bundle"); // NOI18N
105

106     // Special resource bundle to use for this property list
107
private ResourceBundle JavaDoc propertyListBundle;
108     
109     // Probably should put these in utils or something - text for boolean properties
110
// that gets written to sun-xxx.xml.
111
private static final String JavaDoc TEXT_TRUE="true"; // NOI18N
112
private static final String JavaDoc TEXT_FALSE="false"; // NOI18N
113

114
115     /** Creates new form DynamicPropertyPanel */
116     public DynamicPropertyPanel() {
117         // initialization is entirely performed in the init() method due to the
118
// dynamic nature of the controls in this panel.
119
}
120     
121     /** This method is called from within the constructor to
122      * initialize the form.
123      * WARNING: Do NOT modify this code. The content of this method is
124      * always regenerated by the Form Editor.
125      */

126     private void initComponents() {//GEN-BEGIN:initComponents
127
java.awt.GridBagConstraints JavaDoc gridBagConstraints;
128
129         setLayout(new java.awt.GridBagLayout JavaDoc());
130
131     }//GEN-END:initComponents
132

133     
134     // Variables declaration - do not modify//GEN-BEGIN:variables
135
// End of variables declaration//GEN-END:variables
136

137     private void initUserComponents() {
138         
139         // Create the custom editors and cache some sizing values
140
//
141
customTextField = new JTextField JavaDoc();
142         customComboBox = new JComboBox JavaDoc();
143         customCheckBox = new JCheckBox JavaDoc();
144         
145         nameRequiredMark = new JLabel JavaDoc();
146         nameLabel = new JLabel JavaDoc();
147         propertiesCombo = new JComboBox JavaDoc();
148         valueRequiredMark = new JLabel JavaDoc();
149         valueLabel = new JLabel JavaDoc();
150         customEditor = customTextField; // Use text field initially.
151

152         GridBagConstraints JavaDoc gridBagConstraints;
153         
154         int textFieldHeight = customTextField.getPreferredSize().height;
155         int comboBoxHeight = customComboBox.getPreferredSize().height;
156         int checkBoxHeight = customCheckBox.getPreferredSize().height;
157         normalizedHeight = Math.max(textFieldHeight, Math.max(comboBoxHeight, checkBoxHeight));
158         
159         // Add controls
160
//
161
nameRequiredMark.setText(localBundle.getString("LBL_RequiredMark")); // NOI18N
162
nameRequiredMark.setLabelFor(propertiesCombo);
163         gridBagConstraints = new GridBagConstraints JavaDoc();
164         gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
165         gridBagConstraints.insets = new Insets JavaDoc(12, 12, 0, 0);
166         nameRequiredMark.getAccessibleContext().setAccessibleName(localBundle.getString("ACSN_RequiredMark")); // NOI18N
167
nameRequiredMark.getAccessibleContext().setAccessibleDescription(localBundle.getString("ACSD_RequiredMark")); // NOI18N
168
add(nameRequiredMark, gridBagConstraints);
169         
170         nameLabel.setText(localBundle.getString("LBL_Name_1")); // NOI18N
171
nameLabel.setDisplayedMnemonic(localBundle.getString("MNE_Name").charAt(0)); // NOI18N
172
nameLabel.setLabelFor(propertiesCombo);
173         gridBagConstraints = new GridBagConstraints JavaDoc();
174         gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
175         gridBagConstraints.insets = new Insets JavaDoc(12, 6, 0, 0);
176         add(nameLabel, gridBagConstraints);
177         
178         propertiesCombo.setEditable(isEditable);
179         gridBagConstraints = new GridBagConstraints JavaDoc();
180         gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER;
181         gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
182         gridBagConstraints.insets = new Insets JavaDoc(12, 6, 0, 11);
183         gridBagConstraints.weightx = 1.0;
184         propertiesCombo.getAccessibleContext().setAccessibleName(localBundle.getString("ACSN_Name")); // NOI18N
185
propertiesCombo.getAccessibleContext().setAccessibleDescription(localBundle.getString("ACSD_Name")); // NOI18N
186
add(propertiesCombo, gridBagConstraints);
187         
188         propertiesCombo.addActionListener(new java.awt.event.ActionListener JavaDoc() {
189             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
190                 handlePropertiesComboActionPerformed(evt);
191             }
192         });
193         
194         int valueBelow = (hasDescription ? 0 : 11);
195         
196         valueRequiredMark.setText(localBundle.getString("LBL_RequiredMark")); // NOI18N
197
valueRequiredMark.setLabelFor(customEditor);
198         gridBagConstraints = new GridBagConstraints JavaDoc();
199         gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
200         gridBagConstraints.insets = new Insets JavaDoc(6, 12, valueBelow, 0);
201         valueRequiredMark.getAccessibleContext().setAccessibleName(localBundle.getString("ACSN_RequiredMark")); // NOI18N
202
valueRequiredMark.getAccessibleContext().setAccessibleDescription(localBundle.getString("ACSD_RequiredMark")); // NOI18N
203
add(valueRequiredMark, gridBagConstraints);
204         
205         valueLabel.setText(localBundle.getString("LBL_Value_1")); // NOI18N
206
valueLabel.setDisplayedMnemonic(localBundle.getString("MNE_Value").charAt(0)); // NOI18N
207
valueLabel.setLabelFor(customEditor);
208         gridBagConstraints = new GridBagConstraints JavaDoc();
209         gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
210         gridBagConstraints.insets = new Insets JavaDoc(6, 6, valueBelow, 0);
211         add(valueLabel, gridBagConstraints);
212         
213         int extraHeight = normalizedHeight - textFieldHeight;
214         int extraBelow = extraHeight/2;
215         int extraAbove = extraHeight-extraBelow;
216         
217         gridBagConstraints = new GridBagConstraints JavaDoc();
218         gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER;
219         gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
220         gridBagConstraints.insets = new Insets JavaDoc(extraAbove+6, 6, extraBelow + valueBelow, 11);
221         gridBagConstraints.weightx = 1.0;
222         customTextField.getAccessibleContext().setAccessibleName(localBundle.getString("ACSN_Value")); // NOI18N
223
customTextField.getAccessibleContext().setAccessibleDescription(localBundle.getString("ACSD_Value")); // NOI18N
224
customComboBox.getAccessibleContext().setAccessibleName(localBundle.getString("ACSN_Value")); // NOI18N
225
customComboBox.getAccessibleContext().setAccessibleDescription(localBundle.getString("ACSD_Value")); // NOI18N
226
customCheckBox.getAccessibleContext().setAccessibleName(localBundle.getString("ACSN_Value")); // NOI18N
227
customCheckBox.getAccessibleContext().setAccessibleDescription(localBundle.getString("ACSD_Value")); // NOI18N
228
add(customEditor, gridBagConstraints);
229         
230         if(hasDescription) {
231             JLabel JavaDoc descRequiredMark = new JLabel JavaDoc();
232             JLabel JavaDoc descLabel = new JLabel JavaDoc();
233             descriptionField = new JTextField JavaDoc();
234
235             // Description required mark is just filler, as description is never
236
// required. But we need it to make the layout look nice.
237
gridBagConstraints = new GridBagConstraints JavaDoc();
238             gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
239             gridBagConstraints.insets = new Insets JavaDoc(6, 12, 11, 0);
240             add(descRequiredMark, gridBagConstraints);
241         
242             descLabel.setText(localBundle.getString("LBL_Description_1")); // NOI18N
243
descLabel.setDisplayedMnemonic(localBundle.getString("MNE_Description").charAt(0)); // NOI18N
244
descLabel.setLabelFor(descriptionField);
245             gridBagConstraints = new GridBagConstraints JavaDoc();
246             gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
247             gridBagConstraints.insets = new Insets JavaDoc(6, 6, 11, 0);
248             add(descLabel, gridBagConstraints);
249
250             gridBagConstraints = new GridBagConstraints JavaDoc();
251             gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER;
252             gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
253             gridBagConstraints.insets = new Insets JavaDoc(6, 6, 11, 11);
254             gridBagConstraints.weightx = 1.0;
255             descriptionField.getAccessibleContext().setAccessibleName(localBundle.getString("ACSN_Description")); // NOI18N
256
descriptionField.getAccessibleContext().setAccessibleDescription(localBundle.getString("ACSD_Description")); // NOI18N
257
add(descriptionField, gridBagConstraints);
258             
259             descriptionField.addKeyListener(new java.awt.event.KeyAdapter JavaDoc() {
260                 public void keyReleased(java.awt.event.KeyEvent JavaDoc evt) {
261                     handleDescriptionFieldKeyReleased(evt);
262                 }
263             });
264         }
265         
266         // Add listeners to custom editors
267
customTextField.addKeyListener(new java.awt.event.KeyAdapter JavaDoc() {
268             public void keyReleased(java.awt.event.KeyEvent JavaDoc evt) {
269                 handleCustomTextFieldKeyReleased(evt);
270             }
271         });
272         
273         customCheckBox.addItemListener(new java.awt.event.ItemListener JavaDoc() {
274             public void itemStateChanged(java.awt.event.ItemEvent JavaDoc evt) {
275                 handleCustomCheckBoxItemStateChanged(evt);
276             }
277         });
278         
279         customComboBox.addActionListener(new java.awt.event.ActionListener JavaDoc() {
280             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
281                 handleCustomComboBoxActionPerformed(evt);
282             }
283         });
284         
285         // Create and set data model for property selector
286
//
287
buildMappings();
288         propertyListModel = new DefaultComboBoxModel JavaDoc();
289         for(Iterator JavaDoc iter = paramMappings.iterator(); iter.hasNext(); ) {
290             propertyListModel.addElement((ParamMapping) iter.next());
291         }
292         propertiesCombo.setModel(propertyListModel);
293     }
294     
295     private void handleCustomTextFieldKeyReleased(java.awt.event.KeyEvent JavaDoc evt) {
296         if(customEditor == customTextField) {
297             value = customTextField.getText();
298             firePropertyChange(Constants.USER_DATA_CHANGED, null, null);
299         }
300     }
301
302     private void handleCustomCheckBoxItemStateChanged(java.awt.event.ItemEvent JavaDoc evt) {
303         if(customEditor == customCheckBox) {
304             value = Utils.interpretCheckboxState(evt) ? TEXT_TRUE : TEXT_FALSE;
305             firePropertyChange(Constants.USER_DATA_CHANGED, null, null);
306         }
307     }
308     
309     private void handleCustomComboBoxActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
310         if(customEditor == customComboBox) {
311             if("comboBoxChanged".equals(evt.getActionCommand())) { // NOI18N
312
Object JavaDoc selectedItem = customComboBox.getSelectedItem();
313                 
314                 if(selectedItem instanceof String JavaDoc) {
315                     value = (String JavaDoc) selectedItem;
316                 } else if(selectedItem instanceof CharsetMapping) {
317                     value = ((CharsetMapping) selectedItem).getCharset().toString();
318                 } else if(selectedItem instanceof LocaleMapping) {
319                     value = ((LocaleMapping) selectedItem).getLocale().toString();
320                 }
321                 
322                 firePropertyChange(Constants.USER_DATA_CHANGED, null, null);
323             }
324         }
325     }
326
327     private void handleDescriptionFieldKeyReleased(java.awt.event.KeyEvent JavaDoc evt) {
328         if(hasDescription) {
329             description = descriptionField.getText();
330             firePropertyChange(Constants.USER_DATA_CHANGED, null, null);
331         }
332     }
333     
334     private void handlePropertiesComboActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
335         if("comboBoxChanged".equals(evt.getActionCommand())) { // NOI18N
336
Object JavaDoc selectedItem = propertyListModel.getSelectedItem();
337 // System.out.println("property selected: is type: " + selectedItem.getClass().getName());
338
if(selectedItem instanceof ParamMapping) {
339                 // param item selected
340
nameMapping = (ParamMapping) selectedItem;
341                 selectProperty(nameMapping);
342             } else if(selectedItem instanceof String JavaDoc) { // && evt.getActionCommand().equals("comboBoxEdited")) {
343
// typed in item selected
344
nameMapping = null;
345                 name = (String JavaDoc) selectedItem;
346                 
347                 // add the selected item to the list.
348
if(propertyListModel.getIndexOf(selectedItem) == -1) {
349                     propertyListModel.addElement(selectedItem);
350                 }
351                 
352                 enableTextFields(true);
353                 displayCustomEditor(customTextField);
354             }
355             
356             firePropertyChange(Constants.USER_DATA_CHANGED, null, null);
357         }
358     }
359     
360     private void selectProperty(ParamMapping pm) {
361         PropertyParam param = pm.getParam();
362         if(param != null) {
363             ParamType paramType = param.getParamType();
364             String JavaDoc type = paramType.getType();
365             enableTextFields(true);
366             
367             valueRequiredMark.setText(paramType.getRequired().equals(TEXT_TRUE) ?
368                 localBundle.getString("LBL_RequiredMark") : ""); // NOI18N
369
String JavaDoc paramLabel = param.getParamLabel();
370             if(paramLabel != null) {
371                 valueLabel.setText(propertyListBundle.getString(paramLabel) + " :"); // NOI18N
372
} else {
373                 valueLabel.setText(localBundle.getString("LBL_Value_1")); // NOI18N
374
}
375
376             value = param.getDefaultValue();
377             
378             if(type.equals("boolean")) { // NOI18N
379
customCheckBox.setSelected(value.equals(TEXT_TRUE));
380                 displayCustomEditor(customCheckBox);
381             } else if(type.equals("text")) { // NOI18N
382
customTextField.setText(value);
383                 customTextField.setCaretPosition(0);
384                 displayCustomEditor(customTextField);
385             } else if(type.equals("number")) { // NOI18N
386
customTextField.setText(value);
387                 customTextField.setCaretPosition(0);
388                 displayCustomEditor(customTextField);
389             } else if(type.equals("list")) { // NOI18N
390
// get model list and set model to custom combo box
391
DefaultComboBoxModel JavaDoc valueListModel = new DefaultComboBoxModel JavaDoc();
392                 Object JavaDoc defaultValue = value;
393                 
394                 if(paramType.isParamCharset()) {
395                     SortedMap JavaDoc charsets = CharsetMapping.getSortedAvailableCharsetMappings();
396                     for(Iterator JavaDoc iter = charsets.entrySet().iterator(); iter.hasNext(); ) {
397                         CharsetMapping cm = (CharsetMapping) ((Map.Entry JavaDoc) iter.next()).getValue();
398                         valueListModel.addElement(cm);
399                     }
400                     
401                     if(value != null) {
402                         defaultValue = CharsetMapping.getCharsetMapping(value);
403                     } else {
404                         defaultValue = CharsetMapping.getCharsetMapping("UTF8");
405                     }
406                 } else if(paramType.isParamLocale()) {
407                     SortedMap JavaDoc locales = LocaleMapping.getSortedAvailableLocaleMappings();
408                     for(Iterator JavaDoc iter = locales.entrySet().iterator(); iter.hasNext(); ) {
409                         LocaleMapping lm = (LocaleMapping) ((Map.Entry JavaDoc) iter.next()).getValue();
410                         valueListModel.addElement(lm);
411                     }
412                     
413                     if(value != null) {
414                         defaultValue = LocaleMapping.getLocaleMapping(value);
415                     } else {
416                         defaultValue = LocaleMapping.getLocaleMapping(Locale.getDefault());
417                     }
418                 } else {
419                     for(int i = 0, n = paramType.sizeParamValue(); i < n; i++) {
420                         valueListModel.addElement(paramType.getParamValue(i));
421                     }
422                     
423                     // Defaults to first item if none specified.
424
if(defaultValue == null) {
425                         defaultValue = valueListModel.getElementAt(0);
426                     }
427                 }
428                 
429                 customComboBox.setModel(valueListModel);
430                 customComboBox.setEditable(paramType.getEditable().equals(TEXT_TRUE));
431                 customComboBox.setSelectedItem(defaultValue);
432                 
433                 displayCustomEditor(customComboBox);
434             }
435             
436             // Show default description, if there is one.
437
if(hasDescription) {
438                 String JavaDoc defaultDesc = param.getParamDescription();
439                 if(defaultDesc != null) {
440                     description = propertyListBundle.getString(defaultDesc);
441                     descriptionField.setText(description);
442                     descriptionField.setCaretPosition(0);
443                 }
444             }
445         } else {
446             // null param means "blank" property is selected
447
// use disabled readonly edit control for value entry component.
448
enableTextFields(false);
449             displayCustomEditor(customTextField);
450         }
451     }
452     
453     private void buildMappings() {
454         List JavaDoc properties = theList.fetchPropertyParamList();
455         paramMappings = new ArrayList JavaDoc(properties.size()+1);
456         
457         // only non-editable property lists can use the null mapping.
458
if(!isEditable) {
459             paramMappings.add(new ParamMapping(null)); // Represents blank entry
460
}
461         
462         for(Iterator JavaDoc iter = properties.iterator(); iter.hasNext(); ) {
463             PropertyParam pp = (PropertyParam) iter.next();
464             paramMappings.add(new ParamMapping(pp));
465         }
466     }
467     
468     private void displayCustomEditor(JComponent JavaDoc newCustomEditor) {
469         if(customEditor != newCustomEditor) {
470             int extraHeight = normalizedHeight - newCustomEditor.getPreferredSize().height;
471             int extraBelow = extraHeight/2;
472             int extraAbove = extraHeight-extraBelow;
473             int valueBelow = (hasDescription ? 0 : 11);
474             
475             GridBagConstraints JavaDoc constraints = new GridBagConstraints JavaDoc();
476             constraints.gridwidth = GridBagConstraints.REMAINDER;
477             constraints.fill = GridBagConstraints.HORIZONTAL;
478             constraints.insets = new Insets JavaDoc(extraAbove+6, 6, extraBelow + valueBelow, 11);
479             constraints.weightx = 1.0;
480             
481             // Reset labels
482
valueRequiredMark.setLabelFor(newCustomEditor);
483             valueLabel.setLabelFor(newCustomEditor);
484             
485             // Remove old control, add the new one, and display them.
486
int customEditorIndex = componentIndexOf(customEditor);
487             remove(customEditor);
488             add(newCustomEditor, constraints, customEditorIndex);
489             
490             // Repack the controls if we're already displayed -- if parent is null
491
// then there is no need to repack yet.
492
Window JavaDoc parentWindow = getParentWindow();
493             if(parentWindow != null) {
494                 parentWindow.pack();
495             }
496             
497             // !PW I'm not sure if this is a hack, or the real fix for this.
498
// For some reason, when the new control is smaller than the old
499
// control (though we've increased the insets to account for this),
500
// there is a repainting issue where the non-overlapped parts of the
501
// old control do not get erased. So, after we've displayed the new
502
// control (via pack()), we invalidate the region occupied by the
503
// entire control, including any extra space we added.
504
//
505
Rectangle JavaDoc bounds = newCustomEditor.getBounds(null);
506             bounds.y -= extraAbove;
507             bounds.height += extraHeight;
508             repaint(bounds);
509             
510             customEditor = newCustomEditor;
511         }
512     }
513     
514     private int componentIndexOf(JComponent JavaDoc control) {
515         int result = -1;
516         
517         Component JavaDoc [] children = getComponents();
518         for(int i = 0; i < children.length; i++) {
519             if(control == children[i]) {
520                 result = i;
521                 break;
522             }
523         }
524         
525         return result;
526     }
527     
528     private void enableTextFields(boolean flag) {
529         value = null;
530         customTextField.setText(value);
531         customTextField.setEditable(flag);
532         customTextField.setEnabled(flag);
533
534         if(hasDescription) {
535             description = null;
536             descriptionField.setText(description);
537             descriptionField.setEditable(flag);
538             descriptionField.setEnabled(flag);
539         }
540     }
541     
542     private Window JavaDoc getParentWindow() {
543         for(Container JavaDoc parent = getParent(); parent != null; parent = parent.getParent()) {
544             if(parent instanceof Window JavaDoc) {
545                 return (Window JavaDoc) parent;
546             }
547         }
548         
549         return null;
550     }
551     
552     /** -----------------------------------------------------------------------
553      * GenericTableDialogPanelAccessor implementation
554      */

555     // Field indices (maps to values[] handled by get/setValues()
556
private static final int NAME_FIELD = 0;
557     private static final int VALUE_FIELD = 1;
558     private static final int DESCRIPTION_FIELD = 2;
559     private static final int NUM_FIELDS_NO_DESCRIPTION = 2; // Number of objects expected in get/setValue methods.
560
private static final int NUM_FIELDS_WITH_DESCRIPTION = 3; // Number of objects expected in get/setValue methods.
561

562     public void init(ASDDVersion asVersion, int preferredWidth, List JavaDoc entries, Object JavaDoc data) {
563         theList = (PropertyList) data;
564         hasDescription = theList.getDescription().equals(TEXT_TRUE);
565         isEditable = theList.getEditable().equals(TEXT_TRUE);
566         
567         String JavaDoc bundlePath = theList.getBundlePath();
568         if(bundlePath != null) {
569             propertyListBundle = ResourceBundle.getBundle(bundlePath);
570         }
571         
572         initComponents();
573         initUserComponents();
574         
575         setPreferredSize(new Dimension JavaDoc(preferredWidth, getPreferredSize().height));
576         
577         if(!isEditable) {
578             // If this is a new operation, select the null property, disable the
579
// entry fields and offer name selection hint.
580
selectProperty((ParamMapping) paramMappings.get(0));
581         }
582     }
583     
584     public Object JavaDoc[] getValues() {
585         Object JavaDoc [] result;
586         
587         if(hasDescription) {
588             result = new Object JavaDoc[NUM_FIELDS_WITH_DESCRIPTION];
589         } else {
590             result = new Object JavaDoc[NUM_FIELDS_NO_DESCRIPTION];
591         }
592         
593         if(nameMapping != null) {
594             PropertyParam param = nameMapping.getParam();
595             if(param != null) {
596                 result[NAME_FIELD] = param.getParamName();
597             } else {
598                 result[NAME_FIELD] = ""; // NOI18N
599
}
600         } else {
601             result[NAME_FIELD] = name;
602         }
603
604         result[VALUE_FIELD] = value;
605         
606         if(hasDescription) {
607             result[DESCRIPTION_FIELD] = description;
608         }
609         
610         return result;
611     }
612     
613     public void setValues(Object JavaDoc[] values) {
614         // Now calling this method with null if this is a <new> action, so
615
// set values to default array and set <new> vs. <edit> flag.
616
if(values == null) {
617             values = new Object JavaDoc [hasDescription ? NUM_FIELDS_WITH_DESCRIPTION : NUM_FIELDS_NO_DESCRIPTION];
618             values[NAME_FIELD] = null;
619             values[VALUE_FIELD] = null;
620             
621             if(hasDescription) {
622                 values[DESCRIPTION_FIELD] = null;
623             }
624             
625             isEditPopup = false;
626         } else {
627             isEditPopup = true;
628         }
629         
630         // Normal, the pattern for this method is to translate each of the value
631
// Objects into native form (string or combobox mapping, usually) and then
632
// set all the components via a setComponentValues() method. But due to
633
// the dynamic nature of the name component, setting the name component
634
// value causes the other data elements to be set to default values. So
635
// we initialize the name component ahead of setting the value and
636
// description data members.
637
name = (String JavaDoc) values[NAME_FIELD];
638         nameMapping = null;
639         
640         // Matching name mapping is convoluted, partly due to the possibility of
641
// ParamMappings with a null Param (which is assumed to be the first
642
// entry if it exists, by the way.
643
//
644
if(name != null && name.length() > 0) {
645             for(Iterator JavaDoc iter = paramMappings.iterator(); iter.hasNext(); ) {
646                 ParamMapping pm = (ParamMapping) iter.next();
647                 PropertyParam param = pm.getParam();
648                 if(param != null && name.equals(param.getParamName())) {
649                     nameMapping = pm;
650                     break;
651                 }
652             }
653         } else if(paramMappings.size() > 0) {
654             ParamMapping pm = (ParamMapping) paramMappings.get(0);
655             if(pm.getParam() == null) {
656                 nameMapping = pm;
657             }
658         }
659         
660         if(nameMapping != null) {
661             propertiesCombo.setSelectedItem(nameMapping);
662         } else {
663             // FIXME should only happen with editable combo boxes, but could happen
664
// if the user hand edits - we should ensure appropriate contingencies
665
// in that case.
666
propertiesCombo.setSelectedItem(name);
667         }
668         
669         // setValues is called with null for New popups and with a values array
670
// for edit popups.
671
//
672
// For New popups, default value & description were set when the property
673
// selection field was initialed (to blank, btw).
674
// For Edit popups, we'll disable the name selection field, and set the
675
// value and description fields to the passed in values, as appropriate.
676
if(isEditPopup) {
677             // Disable the name selection field in Edit mode. This makes
678
// validation significantly easier.
679
propertiesCombo.setEnabled(false);
680                     
681             value = (String JavaDoc) values[VALUE_FIELD];
682
683             if(customEditor == customCheckBox) {
684                 customCheckBox.setSelected(Utils.booleanValueOf(value));
685             } else if(customEditor == customTextField) {
686                 customTextField.setText(value);
687                 customTextField.setCaretPosition(0);
688             } else if(customEditor == customComboBox) {
689                 // this combo is just a list of Strings, so no mapping object needed.
690
customComboBox.setSelectedItem(value);
691             }
692
693             if(hasDescription) {
694                 description = (String JavaDoc) values[DESCRIPTION_FIELD];
695                 descriptionField.setText(description);
696                 descriptionField.setCaretPosition(0);
697             }
698         }
699     }
700     
701     public boolean requiredFieldsFilled() {
702         return true;
703     }
704     
705     public Collection JavaDoc getErrors(ValidationSupport validationSupport) {
706         ArrayList JavaDoc errorList = new ArrayList JavaDoc();
707         
708         if(hasEmptyName()) {
709             errorList.add(localBundle.getString("ERR_NameFieldIsEmpty")); // NOI18N
710
} else if(nameMapping != null) {
711             // Only values with a 'param-type' entry can have a validator
712
if(value == null || value.length() == 0) {
713 // errorList.add(localBundle.getString("ERR_ValueFieldIsEmpty"));
714
Object JavaDoc [] args = new Object JavaDoc [1];
715                 args[0] = localBundle.getString("LBL_Value");
716                 errorList.add(MessageFormat.format(localBundle.getString("ERR_SpecifiedFieldIsEmpty"), args));
717             } else {
718                 PropertyParam param = nameMapping.getParam(); // Not null here due to hasEmptyName() call, above
719
ParamType paramType = param.getParamType();
720                 String JavaDoc type = paramType.getType();
721                 String JavaDoc name = param.getParamName();
722
723                 if(type.equals("text")) { // NOI18N
724
validate(value, param.getParamValidator(), name, errorList);
725                 } else if(type.equals("number")) { // NOI18N
726
validateNumber(value, paramType.getParamMin(), paramType.getParamMax(), errorList);
727                 } else if(type.equals("list")) { // NOI18N
728
validate(value, param.getParamValidator(), name, errorList);
729                 }
730             }
731         }
732         
733         return errorList;
734     }
735     
736     /** Determine if the name field represents a blank value. This is a bit
737      * complicated since the name could be a ParamMapping that may or may not
738      * be null, or it could be a String (that may or may not be null).
739      */

740     private boolean hasEmptyName() {
741         boolean result = true;
742         
743         if(nameMapping != null && nameMapping.getParam() != null) {
744             result = false; // param name is not null
745
} else if(nameMapping == null && name != null && name.length() > 0) {
746             result = false; // param name is null, but typed-in name is not empty
747
}
748         
749         return result;
750     }
751     
752     /** Validate the numeric string passed in with optional range, and add any
753      * error messages to the list.
754      *
755      * @param theNumber The number (as string) to validate
756      * @param paramMin The minimum value (can be null)
757      * @param paramMax The maximum value (can be null)
758      * @param errorList The list to add any error messages to.
759      */

760     private void validateNumber(String JavaDoc theNumber, String JavaDoc paramMin, String JavaDoc paramMax, List JavaDoc errorList) {
761         try {
762             long x = Long.parseLong(theNumber);
763             long min = Long.MIN_VALUE;
764             long max = Long.MAX_VALUE;
765
766             if(paramMin != null) {
767                 min = Long.parseLong(paramMin);
768                 if(x < min) {
769                     Object JavaDoc [] args = new Object JavaDoc [] { theNumber, Long.toString(min) };
770                     errorList.add(MessageFormat.format(
771                         localBundle.getString("ERR_NumberTooLow"), args)); // NOI18N
772
}
773             }
774
775             if(paramMax != null) {
776                 max = Long.parseLong(paramMax);
777                 if(x > max) {
778                     Object JavaDoc [] args = new Object JavaDoc [] { theNumber, Long.toString(max) };
779                     errorList.add(MessageFormat.format(
780                         localBundle.getString("ERR_NumberTooHigh"), args)); // NOI18N
781
}
782             }
783         } catch(NumberFormatException JavaDoc ex) {
784             Object JavaDoc [] args = new Object JavaDoc [] { theNumber };
785             errorList.add(MessageFormat.format(
786                 localBundle.getString("ERR_NumberInvalid"), args)); // NOI18N
787
}
788     }
789     
790     /** Validate the string passed according the to validator specified.
791      *
792      * @param value The string to validate
793      * @param validatorName The name of the validator to look up. (Must have
794      * been defined in validator section of input XML file)
795      * @param proprtyName The name of the property being edited. This is for
796      * any resulting error message.
797      * @param errorList The list to add any error messages to.
798      */

799     private void validate(String JavaDoc value, String JavaDoc validatorName, String JavaDoc propertyName, List JavaDoc errorList) {
800         if(validatorName != null) {
801             Pattern JavaDoc validatorPattern = PropertyListMapping.getValidator(validatorName);
802             if(validatorPattern != null) {
803                 if(!validatorPattern.matcher(value).matches()) {
804                     Object JavaDoc [] args = new Object JavaDoc [] { propertyName, validatorName };
805                     String JavaDoc propInvalidMsg = localBundle.getString("ERR_PropertyValueInvalid"); // NOI18N
806
errorList.add(MessageFormat.format(propInvalidMsg, args));
807                 }
808             }
809         }
810     }
811     
812 }
813
Popular Tags