KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > util > gui > propedit > MultiEditorPane


1 package net.suberic.util.gui.propedit;
2 import javax.swing.*;
3 import net.suberic.util.*;
4 import java.util.*;
5 import javax.swing.event.*;
6 import javax.swing.table.DefaultTableModel JavaDoc;
7 import javax.swing.table.JTableHeader JavaDoc;
8 import java.awt.Container JavaDoc;
9 import java.awt.Component JavaDoc;
10 import java.awt.event.*;
11
12 /**
13  * This class will make an editor for a list of elements, where each of
14  * the elements has a set of subproperties.
15  *
16  * Configuration is as follows:
17  *
18  * Foo.propertyType=Multi -- shows this is a property editor for an
19  * attribute with multiple values.
20  *
21  * Foo.editableFields=.bar:.baz -- shows which subfields are to be edited
22  *
23  *
24  * So if your Foo property equals "fooOne:fooTwo", then you'll end up with
25  * a MultiPropertyEditor that has an entry for fooOne and fooTwo, along with
26  * ways to add and remove items.
27  *
28  * If your Foo.editableFields=bar:baz, then your editor screen for, say,
29  * fooOne will have two entries, one for Foo.fooOne.bar, and the other for
30  * Foo.fooOne.baz. These editors will use Foo.editableFields.bar and
31  * Foo.editableFields.baz for templates.
32  *
33  */

34
35 public class MultiEditorPane extends CompositeSwingPropertyEditor implements ListSelectionListener {
36   protected JTable optionTable;
37   JPanel entryPanel;
38   protected JPanel buttonPanel;
39
40   List<JButton> buttonList;
41   boolean changed = false;
42   List<String JavaDoc> removeValues = new ArrayList<String JavaDoc>();
43   String JavaDoc propertyTemplate;
44   List<String JavaDoc> displayProperties;
45
46   protected Action[] mDefaultActions;
47
48   /**
49    * This configures this editor with the following values.
50    *
51    * @param propertyName The property to be edited.
52    * @param template The property that will define the layout of the
53    * editor.
54    * @param manager The PropertyEditorManager that will manage the
55    * changes.
56    */

57   public void configureEditor(String JavaDoc propertyName, String JavaDoc template, String JavaDoc propertyBaseName, PropertyEditorManager newManager) {
58     getLogger().fine("creating MultiEditorPane for property " + propertyName + ", template " + template);
59     configureBasic(propertyName, template, propertyBaseName, newManager);
60
61     // create the current list of edited items. so if this is a User list,
62
// these values might be 'allen', 'deborah', 'marc', 'jessica', etc.
63

64     List<String JavaDoc> optionList = manager.getPropertyAsList(property, "");
65
66     displayProperties = manager.getPropertyAsList(editorTemplate + "._displayProperties", "");
67
68     optionTable = createOptionTable(optionList, displayProperties);
69     JScrollPane optionScrollPane = new JScrollPane(optionTable);
70
71     buttonPanel = createButtonPanel();
72
73     getLogger().fine("MultiEditorPane for property " + propertyName + ", template " + template);
74
75     doEditorPaneLayout(optionScrollPane, buttonPanel);
76
77     updateEditorEnabled();
78
79     manager.registerPropertyEditor(property, this);
80
81   }
82
83   /**
84    * Lays out the MultiEditorPane.
85    */

86   public void doEditorPaneLayout(Component JavaDoc listPanel, Component JavaDoc buttonPanel) {
87     SpringLayout layout = new SpringLayout();
88     this.setLayout(layout);
89
90     this.add(listPanel);
91     this.add(buttonPanel);
92
93     SpringLayout.Constraints ospConstraints = layout.getConstraints(listPanel);
94     SpringLayout.Constraints buttonConstraints = layout.getConstraints(buttonPanel);
95
96     Spring panelHeight = Spring.constant(0);
97     panelHeight = Spring.max(panelHeight, ospConstraints.getHeight());
98     panelHeight = Spring.max(panelHeight, buttonConstraints.getHeight());
99
100     ospConstraints.setHeight(panelHeight);
101     buttonConstraints.setHeight(panelHeight);
102
103     layout.putConstraint(SpringLayout.WEST, listPanel, 5, SpringLayout.WEST, this);
104     layout.putConstraint(SpringLayout.NORTH, listPanel, 5, SpringLayout.NORTH, this);
105     layout.putConstraint(SpringLayout.SOUTH, this, 5, SpringLayout.SOUTH, listPanel);
106
107     layout.putConstraint(SpringLayout.WEST, buttonPanel, 5, SpringLayout.EAST, listPanel);
108     layout.putConstraint(SpringLayout.NORTH, buttonPanel, 5, SpringLayout.NORTH, this);
109     layout.putConstraint(SpringLayout.EAST, this, 5 ,SpringLayout.EAST, buttonPanel);
110
111
112   }
113
114   /**
115    * Creates the Option Table. This is a JTable that lists the various
116    * items that have been created.
117    */

118   private JTable createOptionTable(List<String JavaDoc> optionList, List<String JavaDoc> pDisplayProperties) {
119     // first get the display properties and their labels.
120
Vector columnLabels = new Vector();
121     // first one is always the id.
122
columnLabels.add(manager.getProperty(editorTemplate + "._label", editorTemplate));
123     for (String JavaDoc subProperty: pDisplayProperties) {
124       getLogger().fine("adding label for " + subProperty);
125
126       String JavaDoc label = manager.getProperty(editorTemplate + "._displayProperties." + subProperty + ".label", subProperty);
127       columnLabels.add(label);
128     }
129
130     DefaultTableModel JavaDoc dtm = new DefaultTableModel JavaDoc(columnLabels, 0);
131
132     // now add the properties.
133

134     for (String JavaDoc option: optionList) {
135       Vector optionValues = createTableEntry(option, pDisplayProperties);
136       dtm.addRow(optionValues);
137     }
138
139     JTable returnValue = new JTable(dtm);
140     returnValue.setCellSelectionEnabled(false);
141     returnValue.setColumnSelectionAllowed(false);
142     returnValue.setRowSelectionAllowed(true);
143     returnValue.setShowGrid(false);
144
145     returnValue.getSelectionModel().addListSelectionListener(this);
146     if (returnValue.getRowCount() > 0) {
147       returnValue.setRowSelectionInterval(0,0);
148     }
149     return returnValue;
150   }
151
152   /**
153    * Adds the given property to the property table.
154    */

155   public Vector createTableEntry(String JavaDoc option, List<String JavaDoc> pDisplayProperties) {
156     Vector optionValues = new Vector();
157     // first one is always the id, at least for now.
158
optionValues.add(option);
159     for (String JavaDoc subProperty: pDisplayProperties) {
160       getLogger().fine("adding display property for " + option + "." + subProperty);
161       optionValues.add(manager.getProperty(property + "." + option + "." + subProperty, subProperty));
162     }
163
164     return optionValues;
165   }
166
167   /**
168    * Creates the box which holds the "Add", "Edit", and "Remove" buttons.
169    */

170   protected JPanel createButtonPanel() {
171     getLogger().fine("creating buttons.");
172
173     createActions();
174
175     buttonList = new ArrayList<JButton>();
176     JPanel returnValue = new JPanel();
177     SpringLayout layout = new SpringLayout();
178     returnValue.setLayout(layout);
179
180     // FIXME i18n
181
JButton addButton = createButton("Add", getAction("editor-add"), true);
182
183     JButton editButton = createButton("Edit", getAction("editor-edit"), true);
184
185     JButton removeButton = createButton("Remove", getAction("editor-delete"), false);
186
187     returnValue.add(addButton);
188     returnValue.add(editButton);
189     returnValue.add(removeButton);
190
191     layout.putConstraint(SpringLayout.NORTH, addButton, 0, SpringLayout.NORTH, returnValue);
192     layout.putConstraint(SpringLayout.WEST, addButton, 5 ,SpringLayout.WEST, returnValue);
193     layout.putConstraint(SpringLayout.EAST, returnValue, 5 ,SpringLayout.EAST, addButton);
194
195     layout.putConstraint(SpringLayout.NORTH, editButton, 5, SpringLayout.SOUTH, addButton);
196     layout.putConstraint(SpringLayout.WEST, editButton, 5 ,SpringLayout.WEST, returnValue);
197
198     layout.putConstraint(SpringLayout.NORTH, removeButton, 5, SpringLayout.SOUTH, editButton);
199     layout.putConstraint(SpringLayout.WEST, removeButton, 5 ,SpringLayout.WEST, returnValue);
200
201     Spring buttonWidth = Spring.constant(0);
202
203     SpringLayout.Constraints addConstraints = layout.getConstraints(addButton);
204     SpringLayout.Constraints editConstraints = layout.getConstraints(editButton);
205     SpringLayout.Constraints removeConstraints = layout.getConstraints(removeButton);
206
207     buttonWidth = Spring.max(buttonWidth, addConstraints.getWidth());
208     buttonWidth = Spring.max(buttonWidth, editConstraints.getWidth());
209     buttonWidth = Spring.max(buttonWidth, removeConstraints.getWidth());
210
211     addConstraints.setWidth(buttonWidth);
212     editConstraints.setWidth(buttonWidth);
213     removeConstraints.setWidth(buttonWidth);
214
215     SpringLayout.Constraints panelConstraints = layout.getConstraints(returnValue);
216     //panelConstraints.setWidth(Spring.sum(buttonWidth, Spring.constant(10)));
217

218     return returnValue;
219   }
220
221   /**
222    * Creates the actions for this editor.
223    */

224   protected void createActions() {
225     mDefaultActions = new Action[] {
226       new AddAction(),
227       new EditAction(),
228       new DeleteAction()
229     };
230   }
231
232   /**
233    * Creates a Button for the ButtonBox with the appropriate label and
234    * Action.
235    */

236   private JButton createButton(String JavaDoc label, Action e, boolean isDefault) {
237     JButton thisButton;
238
239     thisButton = new JButton(manager.getProperty("label." + label, label));
240     String JavaDoc mnemonic = manager.getProperty("label." + label + ".mnemonic", "");
241     if (!mnemonic.equals(""))
242       thisButton.setMnemonic(mnemonic.charAt(0));
243
244     thisButton.setSelected(isDefault);
245
246     thisButton.addActionListener(e);
247
248     buttonList.add(thisButton);
249     return thisButton;
250   }
251
252
253   /**
254    * Called when the selected value changed. Should result in the
255    * entryPane changing.
256    */

257   public void valueChanged(ListSelectionEvent e) {
258
259   }
260
261   /**
262    * Adds a new value to the edited List.
263    */

264   public void addNewValue(String JavaDoc newValueName) {
265     try {
266       List<String JavaDoc> newValueList = new ArrayList<String JavaDoc>();
267       for (int i = 0; i < optionTable.getRowCount(); i++) {
268         newValueList.add((String JavaDoc) optionTable.getValueAt(i, 0));
269       }
270       newValueList.add(newValueName);
271       String JavaDoc newValue = VariableBundle.convertToString(newValueList);
272       firePropertyChangingEvent(newValue) ;
273       Vector newValueVector = createTableEntry(newValueName, displayProperties);
274       ((DefaultTableModel JavaDoc)optionTable.getModel()).addRow(newValueVector);
275       firePropertyChangedEvent(newValue);
276       this.setChanged(true);
277
278       optionTable.getSelectionModel().setSelectionInterval(optionTable.getModel().getRowCount(), optionTable.getModel().getRowCount() -1);
279     } catch (PropertyValueVetoException pvve) {
280       manager.getFactory().showError(getPropertyEditorPane().getContainer(), "Error adding value " + newValueName + " to " + property + ": " + pvve.getReason());
281     }
282   }
283
284   /**
285    * Adds a new value to the edited List.
286    */

287   protected void addNewValue(String JavaDoc newValueName, Container JavaDoc container) {
288     if (newValueName == null || newValueName.length() == 0)
289       return;
290
291     try {
292       List<String JavaDoc> newValueList = new ArrayList<String JavaDoc>();
293       for (int i = 0; i < optionTable.getRowCount(); i++) {
294         newValueList.add((String JavaDoc) optionTable.getValueAt(i, 0));
295       }
296       newValueList.add(newValueName);
297       String JavaDoc newValue = VariableBundle.convertToString(newValueList);
298       firePropertyChangingEvent(newValue) ;
299       Vector newValueVector = new Vector();
300       newValueVector.add(newValueName);
301       ((DefaultTableModel JavaDoc)optionTable.getModel()).addRow(newValueVector);
302       firePropertyChangedEvent(newValue);
303       this.setChanged(true);
304
305       optionTable.getSelectionModel().setSelectionInterval(optionTable.getModel().getRowCount(), optionTable.getModel().getRowCount() -1);
306       editSelectedValue(container);
307     } catch (PropertyValueVetoException pvve) {
308       manager.getFactory().showError(container, "Error adding value " + newValueName + " to " + property + ": " + pvve.getReason());
309     }
310   }
311
312   /**
313    * Removes the currently selected value from the edited List.
314    */

315   public void removeSelectedValue() {
316     int selectedRow = optionTable.getSelectedRow();
317     String JavaDoc selValue = (String JavaDoc) optionTable.getValueAt(selectedRow, 0);
318     if (selValue == null)
319       return;
320
321     try {
322       List<String JavaDoc> newValueList = new ArrayList<String JavaDoc>();
323       for (int i = 0; i < optionTable.getRowCount(); i++) {
324         if (i != selectedRow) {
325           newValueList.add((String JavaDoc) optionTable.getValueAt(i, 0));
326         }
327       }
328       String JavaDoc newValue = VariableBundle.convertToString(newValueList);
329       firePropertyChangingEvent(newValue) ;
330       ((DefaultTableModel JavaDoc)optionTable.getModel()).removeRow(selectedRow);
331       firePropertyChangedEvent(newValue);
332
333       removeValues.add(property + "." + selValue);
334
335       this.setChanged(true);
336     } catch (PropertyValueVetoException pvve) {
337       manager.getFactory().showError(this, "Error removing value " + selValue + " from " + property + ": " + pvve.getReason());
338     }
339
340   }
341
342   /**
343    * Edits the currently selected value.
344    */

345   public void editSelectedValue() {
346     editSelectedValue(this.getPropertyEditorPane().getContainer());
347   }
348
349   /**
350    * Edits the currently selected value, using the given Container as an
351    * editor source.
352    */

353   protected void editSelectedValue(Container JavaDoc container) {
354     getLogger().fine("calling editSelectedValue().");
355     int selectedRow = optionTable.getSelectedRow();
356     if (selectedRow != -1) {
357       String JavaDoc valueToEdit = (String JavaDoc) optionTable.getValueAt(selectedRow, 0);
358       String JavaDoc editProperty = property + "." + valueToEdit;
359       getLogger().fine("editing " + editProperty);
360
361       manager.getFactory().showNewEditorWindow(manager.getProperty(editorTemplate + ".label", editProperty), manager.getFactory().createEditor(editProperty, editorTemplate + ".editableFields", editProperty, "Composite", manager), container);
362     } else {
363       getLogger().fine("editSelectedValue(): no selected value.");
364     }
365
366   }
367
368   /**
369    * Puts up a dialog to get a name for the new value.
370    */

371   public String JavaDoc getNewValueName() {
372     boolean goodValue = false;
373     boolean matchFound = false;
374
375     String JavaDoc newName = null;
376     newName = manager.getFactory().showInputDialog(this, manager.getProperty("MultiEditorPane.renameProperty", "Enter new name."));
377
378     while (goodValue == false) {
379       matchFound = false;
380       if (newName != null) {
381
382         for (int i = 0; i < optionTable.getRowCount() && matchFound == false; i++) {
383           if (((String JavaDoc)optionTable.getValueAt(i, 0)).equals(newName))
384             matchFound = true;
385
386         }
387
388         if (matchFound == false)
389           goodValue = true;
390         else
391           newName = manager.getFactory().showInputDialog(this, manager.getProperty("MultiEditorPane.error.duplicateName", "Name already exists:") + " " + newName + "\n" + manager.getProperty("MultiEditorPane.renameProperty", "Enter new name."));
392       } else {
393         goodValue = true;
394       }
395     }
396
397     return newName;
398   }
399
400   /**
401    * This produces a string for the given JList.
402    */

403   public String JavaDoc getStringFromList(DefaultListModel dlm) {
404
405     String JavaDoc retVal;
406     if (dlm.getSize() < 1)
407       return "";
408     else
409       retVal = new String JavaDoc((String JavaDoc)dlm.getElementAt(0));
410
411     for (int i = 1; i < dlm.getSize(); i++) {
412       retVal = retVal.concat(":" + (String JavaDoc)dlm.getElementAt(i));
413     }
414
415     return retVal;
416   }
417
418   /**
419    * Sets the value for this MultiEditorPane.
420    */

421   public void setValue() throws PropertyValueVetoException {
422     if (isEditorEnabled()) {
423
424       if (isChanged()) {
425         getLogger().fine("setting property. property is " + property + "; value is " + getCurrentValue());
426         manager.setProperty(property, getCurrentValue());
427
428         for (String JavaDoc removeProp: removeValues) {
429           //manager.removeProperty(removeValues.get(i));
430
Set<String JavaDoc> subProperties = manager.getPropertyNamesStartingWith(removeProp + ".");
431           for (String JavaDoc subProp: subProperties) {
432             manager.removeProperty(subProp);
433           }
434         }
435         removeValues = new ArrayList<String JavaDoc>();
436
437       }
438     }
439   }
440
441   /**
442    * Returns the current value from the table.
443    */

444   public String JavaDoc getCurrentValue() {
445     List<String JavaDoc> values = new ArrayList<String JavaDoc>();
446     for (int i = 0; i < optionTable.getRowCount(); i++) {
447       values.add((String JavaDoc) optionTable.getValueAt(i, 0));
448     }
449     return VariableBundle.convertToString(values);
450   }
451
452   /**
453    * Resets the default values.
454    */

455   public void resetDefaultValue() throws PropertyValueVetoException {
456
457     //FIXME
458
throw new UnsupportedOperationException JavaDoc("reset not yet implemented for MultiEditorPane.");
459
460     /*
461     removeValues = new Vector();
462
463     if (isChanged()) {
464       firePropertyChangedEvent(originalValue);
465     }
466     */

467   }
468
469   /**
470    * Returns the currently edited values as a Properties object.
471    */

472   public java.util.Properties JavaDoc getValue() {
473     java.util.Properties JavaDoc currentRetValue = new java.util.Properties JavaDoc();
474     currentRetValue.setProperty(property, getCurrentValue());
475     return currentRetValue;
476   }
477
478   /**
479    * Returns whether or not the top-level edited values of this EditorPane
480    * have changed.
481    */

482   public boolean isChanged() {
483     return changed;
484   }
485
486   /**
487    * Sets whether or not the top-level edited values of this EditorPane
488    * have changed.
489    */

490   public void setChanged(boolean newChanged) {
491     changed=newChanged;
492   }
493
494   /**
495    * Returns the entryPanel.
496    */

497   public JPanel getEntryPanel() {
498     return entryPanel;
499   }
500
501   /**
502    * Creates an editor.
503    */

504   public SwingPropertyEditor createEditorPane(String JavaDoc subProperty, String JavaDoc subTemplate) {
505     return (SwingPropertyEditor) manager.getFactory().createEditor(subProperty, subTemplate, "Composite", manager);
506   }
507
508   /**
509    * Run when the PropertyEditor may have changed enabled states.
510    */

511   protected void updateEditorEnabled() {
512     for (int i = 0; i < buttonList.size(); i++) {
513       buttonList.get(i).setEnabled(isEditorEnabled());
514     }
515   }
516
517   /**
518    * Removes the PropertyEditor.
519    */

520   public void remove() {
521     manager.removePropertyEditorListeners(getProperty());
522   }
523
524   /**
525    * Returns the actions associated with this editor.
526    */

527   public Action[] getActions() {
528     return mDefaultActions;
529   }
530
531   /**
532    * Returns the action for the given identifier.
533    */

534   public Action getAction(String JavaDoc name) {
535     for (Action action: mDefaultActions) {
536       if (action.getValue(Action.NAME) != null && action.getValue(Action.NAME).equals(name))
537         return action;
538     }
539
540     return null;
541   }
542
543   public class AddAction extends AbstractAction {
544     public AddAction() {
545       //super("address-add");
546
super("editor-add");
547     }
548
549     public void actionPerformed(ActionEvent e) {
550       /*
551       setBusy(true);
552       performAdd();
553       setBusy(false);
554       */

555       // check to see if we want to add a new value using a
556
// wizard
557
String JavaDoc newValueTemplate = manager.getProperty(editorTemplate + "._addValueTemplate", "");
558       if (newValueTemplate.length() > 0) {
559         manager.getFactory().showNewEditorWindow(manager.getProperty(newValueTemplate + ".label", newValueTemplate), manager.getFactory().createEditor(newValueTemplate, newValueTemplate, manager), getPropertyEditorPane().getContainer());
560
561       } else {
562         addNewValue(getNewValueName(), getPropertyEditorPane().getContainer());
563       }
564
565     }
566   }
567
568   public class EditAction extends AbstractAction {
569     public EditAction() {
570       super("editor-edit");
571     }
572
573     public void actionPerformed(ActionEvent e) {
574       /*
575       setBusy(true);
576       editSelectedValue();
577       setBusy(false);
578       */

579       editSelectedValue();
580     }
581   }
582
583   public class DeleteAction extends AbstractAction {
584     public DeleteAction() {
585       super("editor-delete");
586     }
587
588     public void actionPerformed(ActionEvent e) {
589       removeSelectedValue();
590       /*
591       setBusy(true);
592       performDelete();
593       setBusy(false);
594       */

595     }
596   }
597
598
599 }
600
Popular Tags