source: trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentControl.java@ 13158

Last change on this file since 13158 was 13158, checked in by mdewsnip, 18 years ago

Made the explode metadata prompt have the exploded metadata set selected by default.

  • Property svn:keywords set to Author Date Id Revision
File size: 19.6 KB
Line 
1package org.greenstone.gatherer.cdm;
2
3import java.awt.*;
4import java.awt.event.*;
5import javax.swing.*;
6import javax.swing.event.*;
7
8import java.io.File;
9import java.util.ArrayList;
10import java.util.Collections;
11import java.util.Map;
12import java.util.Iterator;
13
14import org.greenstone.gatherer.Configuration;
15import org.greenstone.gatherer.DebugStream;
16import org.greenstone.gatherer.Dictionary;
17import org.greenstone.gatherer.Gatherer;
18import org.greenstone.gatherer.gui.GComboBox;
19import org.greenstone.gatherer.util.StaticStrings;
20import org.greenstone.gatherer.util.Utility;
21import org.greenstone.gatherer.metadata.MetadataElement;
22import org.greenstone.gatherer.metadata.MetadataSet;
23import org.greenstone.gatherer.metadata.MetadataSetManager;
24import org.greenstone.gatherer.metadata.MetadataTools;
25
26/** This class encapsulates all the technical difficulty of creating a specific control based on an Argument. */
27public class ArgumentControl
28 extends JPanel {
29
30 static protected Dimension LABEL_SIZE = new Dimension(175, 25);
31 static protected Dimension ROW_SIZE = new Dimension(400, 30);
32 /** The Argument this control will be based on. */
33 private Argument argument = null;
34
35 /** A checkbox to allow enabling or diabling of this Argument. */
36 private JCheckBox enabled = null;
37 /** Some form of editor component, such as a JComboBox or JTextField, used to set parameters to an Argument. */
38 private JComponent value_control = null;
39
40 /** Constructor.
41 */
42 public ArgumentControl(Argument argument, boolean is_enabled, String preset_value) {
43 this.argument = argument;
44
45 String tip = "<html>" + argument.getName()+": "+argument.getDescription() + "</html>";
46 tip = Utility.formatHTMLWidth(tip, 80);
47
48 setBackground(Configuration.getColor("coloring.collection_tree_background", false));
49 setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
50 setLayout(new BorderLayout());
51 setPreferredSize(ROW_SIZE);
52
53 if (argument.isRequired()) {
54 JLabel label = new JLabel(argument.getName());
55 label.setOpaque(false);
56 label.setPreferredSize(LABEL_SIZE);
57 label.setToolTipText(tip);
58 add(label, BorderLayout.WEST);
59 } else {
60 enabled = new JCheckBox(argument.getName());
61 enabled.setOpaque(false);
62 enabled.setPreferredSize(LABEL_SIZE);
63 enabled.setToolTipText(tip);
64 add(enabled, BorderLayout.WEST);
65 }
66
67 String initial_value;
68 if (preset_value != null && !preset_value.equals("")) {
69 initial_value = preset_value;
70 }
71 else {
72 initial_value = argument.getValue();
73 }
74 if (initial_value == null || initial_value.equals("")) {
75 initial_value = argument.getDefaultValue();
76 }
77 if (initial_value == null) {
78 initial_value = "";
79 }
80
81 switch(argument.getType()) {
82 case Argument.ENUM:
83 ArrayList option_list = argument.getOptions();
84 value_control = new GComboBox(option_list.toArray(), false, false);
85 selectValue((JComboBox)value_control, initial_value); // also sets the tooltip
86 ((JComboBox)value_control).addActionListener(new ToolTipUpdater());
87 break;
88
89 case Argument.FLAG:
90 // Only need the check box.
91 break;
92
93 case Argument.INTEGER:
94 // Build a spinner
95 int initial_int=0;
96 // If there was an original value, set it.
97 try {
98 initial_int = Integer.parseInt(initial_value);
99 } catch (Exception error) {
100 DebugStream.println("ArgumentControl Error: "+error);
101 }
102 if (initial_int < argument.getMinimum()) {
103 initial_int = argument.getMinimum();
104 } else if (initial_int > argument.getMaximum()) {
105 initial_int = argument.getMaximum();
106 }
107
108 JSpinner spinner = new JSpinner(new SpinnerNumberModel(initial_int, argument.getMinimum(), argument.getMaximum(), 1));
109
110 // And remember it
111 value_control = spinner;
112 break;
113
114 case Argument.REGEXP:
115 case Argument.STRING:
116 value_control = new JTextField(initial_value);
117 break;
118
119 case Argument.LANGUAGE:
120 value_control = new GComboBox(CollectionDesignManager.language_manager.getLanguageCodes().toArray(), false);
121 // we want to display the language name not the code
122 ((JComboBox)value_control).setRenderer(new LanguageListCellRenderer());
123 // Now ensure we have the existing value or default value selected if either exist in our known languages
124 String lang_name = CollectionDesignManager.language_manager.getLanguageName(initial_value);
125 if (lang_name != null) {
126 ((JComboBox)value_control).setSelectedItem(initial_value);
127 }
128 break;
129
130 case Argument.METADATUM:
131 case Argument.METADATA:
132 value_control = new GComboBox(MetadataSetManager.getEveryMetadataSetElement(), false);
133
134 // Editable for advanced modes (allows things like dc.Title,ex.Title)
135 if (Configuration.getMode() > Configuration.ASSISTANT_MODE) {
136 ((JComboBox) value_control).setEditable(true);
137 }
138 // Now ensure we have the existing value or default value selected if either exist.
139 String existing_value = preset_value;
140 if (existing_value == null || existing_value.length() == 0) {
141 existing_value = argument.getValue();
142 }
143 if (existing_value != null && existing_value.length() > 0) {
144 boolean found = selectValue((JComboBox) value_control, existing_value);
145 // It's possible that this is a custom value and so doesn't exist in the combobox
146 if (!found) {
147 // If so, add it then select it
148 ((JComboBox) value_control).addItem(existing_value);
149 ((JComboBox) value_control).setSelectedItem(existing_value);
150 }
151 }
152 else {
153 String default_value = argument.getDefaultValue();
154 if (default_value != null) {
155 // if no namespace for default value, add ex.
156 // won't work if we want to set a non-metadata value
157 if (MetadataTools.getMetadataSetNamespace(default_value).equals("")) {
158 default_value = StaticStrings.EXTRACTED_NAMESPACE+default_value;
159 }
160 selectValue((JComboBox) value_control, default_value);
161 }
162 }
163 break;
164
165 case Argument.METADATA_SET_NAMESPACE:
166 value_control = new JComboBox();
167 // !! Hack for exploding metadata databases: add the (empty) exploded metadata set
168 File exploded_metadata_set_file = new File(Gatherer.getGLIMetadataDirectoryPath() + "exp" + StaticStrings.METADATA_SET_EXTENSION);
169 MetadataSet exploded_metadata_set = new MetadataSet(exploded_metadata_set_file);
170 Gatherer.c_man.importMetadataSet(exploded_metadata_set);
171
172 // All the loaded metadata sets except the extracted metadata set are applicable
173 ArrayList metadata_sets = MetadataSetManager.getMetadataSets();
174 for (int i = metadata_sets.size() - 1; i >= 0; i--) {
175 MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
176 if (!(metadata_set.getNamespace().equals(MetadataSetManager.EXTRACTED_METADATA_NAMESPACE))) {
177 ((JComboBox)value_control).addItem(metadata_set);
178 }
179 }
180
181 selectValue((JComboBox) value_control, initial_value);
182
183 } // end of switch
184
185 // Enable or disable as necessary.
186 if(argument.isRequired() || argument.isAssigned() || is_enabled) {
187 if (enabled != null) {
188 enabled.setSelected(true);
189 }
190 if(value_control != null) {
191 value_control.setOpaque(true);
192 value_control.setBackground(Color.white);
193 value_control.setEnabled(true);
194 if(value_control instanceof JSpinner) {
195 // Set enabled
196 JComponent c = ((JSpinner)value_control).getEditor();
197 if ( c instanceof JSpinner.DefaultEditor ) {
198 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
199 JFormattedTextField field = editor.getTextField();
200 field.setEditable(true);
201 field.setBackground(Color.white);
202 }
203 }
204 }
205 }
206 else {
207 if (enabled != null) {
208 enabled.setSelected(false);
209 }
210 if(value_control != null) {
211 value_control.setOpaque(true);
212 value_control.setBackground(Color.lightGray);
213 value_control.setEnabled(false);
214 if(value_control instanceof JSpinner) {
215 // Set enabled
216 JComponent c = ((JSpinner)value_control).getEditor();
217 if ( c instanceof JSpinner.DefaultEditor ) {
218 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
219 JFormattedTextField field = editor.getTextField();
220 field.setEditable(false);
221 field.setBackground(Color.lightGray);
222 }
223 }
224 }
225 }
226
227 // Listener
228 if(value_control != null) {
229 if (argument.getType() != Argument.ENUM) {
230 // enums have already set tooltips based on option value
231 value_control.setToolTipText(tip);
232 }
233 add(value_control, BorderLayout.CENTER);
234 if (!argument.isRequired()) {
235 enabled.addActionListener(new EnabledListener(value_control));
236 }
237 }
238 }
239
240 public Argument getArgument() {
241 return argument;
242 }
243
244 public String getArgumentName() {
245 return argument.getName();
246 }
247
248 public String getValue() {
249 if(value_control == null) {
250 return null;
251 }
252 if (value_control instanceof JSpinner) {
253 return ((JSpinner)value_control).getValue().toString();
254 }
255 if(value_control instanceof JComboBox) {
256 Object selected_item = ((JComboBox)value_control).getSelectedItem();
257 if (selected_item != null) {
258 if (argument.getType() == Argument.METADATA_SET_NAMESPACE) {
259 return ((MetadataSet) selected_item).getNamespace();
260 }
261 if (selected_item instanceof Argument.ArgumentOption) {
262 return ((Argument.ArgumentOption)selected_item).name;
263 }
264 if (selected_item instanceof MetadataElement) {
265 return ((MetadataElement) selected_item).getFullName();
266 }
267 return selected_item.toString();
268 }
269 return null;
270 }
271 if(value_control instanceof JTextField) {
272 return ((JTextField)value_control).getText();
273 }
274 return null;
275 }
276 /** Retrieve the control used for storing values.
277 * @return JComponent
278 */
279 public JComponent getValueControl() {
280 return value_control;
281 }
282
283 public boolean isEnabled() {
284 if (enabled == null) {
285 return true; // always enabled
286 }
287 return enabled.isSelected();
288 }
289
290
291 /** Identifies this control by returning the name of the Argument it is based on.
292 * @return The name of the Argument as a <strong>String</strong>.
293 * @see org.greenstone.gatherer.cdm.Argument
294 */
295 public String toString() {
296 return argument.getName();
297 }
298 /** Updates the enwrapped Argument using the values provided by the controls.
299 * @return <i>true</i> if the update was successful, <i>false</i> otherwise.
300 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.Argument.ArgumentOption
301 * @see org.greenstone.gatherer.cdm.Language
302 */
303 public boolean updateArgument() {
304 if(argument.isRequired() || enabled.isSelected() ) {
305 argument.setAssigned(false);
306 String result = null;
307 switch(argument.getType()) {
308 case Argument.ENUM:
309 Argument.ArgumentOption option = (Argument.ArgumentOption)((JComboBox)value_control).getSelectedItem();
310 if(option != null && option.name.length() > 0) {
311 argument.setValue(option.name);
312 }
313 else {
314 String args[] = new String[1];
315 args[0] = argument.getName();
316 if(argument.isRequired()) {
317 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
318 }
319 // They've left the field blank
320 else {
321 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
322 argument.setValue(null);
323 }
324 args = null;
325 return false;
326 }
327 argument.setAssigned(true);
328 return true;
329 case Argument.FLAG:
330 // Should have already been handled above.
331 argument.setAssigned(true);
332 return true;
333 case Argument.INTEGER:
334 result = ((JSpinner)value_control).getValue().toString();
335 if(result.length() > 0) {
336 // Test if the value entered is a valid int.
337 try {
338 int x = Integer.parseInt(result);
339 }
340 catch(NumberFormatException nfe) {
341 String args[] = new String[2];
342 args[0] = argument.getName();
343 args[1] = result;
344 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Bad_Integer", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
345 args = null;
346 return false;
347 }
348 argument.setValue(result);
349 }
350 else {
351 String args[] = new String[1];
352 args[0] = argument.getName();
353 if(argument.isRequired()) {
354 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
355 }
356 // They've left the field blank
357 else {
358 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
359 argument.setValue(null);
360 }
361 args = null;
362 return false;
363 }
364 argument.setAssigned(true);
365 return true;
366 case Argument.LANGUAGE:
367 String language = (((JComboBox)value_control).getSelectedItem()).toString();
368 argument.setValue(language);
369 // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
370 argument.setAssigned(true);
371 return true;
372 case Argument.METADATUM:
373 case Argument.METADATA:
374 Object new_value_raw = ((JComboBox) value_control).getSelectedItem();
375 if (new_value_raw instanceof MetadataElement) {
376 argument.setValue(((MetadataElement) new_value_raw).getFullName());
377 }
378 else {
379 // But we have to be careful as an arbitary string object could be zero length
380 String new_value = new_value_raw.toString();
381 ///ystem.err.println("The current value is: " + new_value);
382 if(new_value.length() > 0) {
383 argument.setValue(new_value);
384 }
385 else {
386 String args[] = new String[1];
387 args[0] = argument.getName();
388 if(argument.isRequired()) {
389 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
390 }
391 // They've left the field blank
392 else {
393 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
394 argument.setValue(null);
395 }
396 args = null;
397 return false;
398 }
399 }
400 argument.setAssigned(true);
401 return true;
402 case Argument.REGEXP:
403 case Argument.STRING:
404 result = ((JTextField)value_control).getText();
405 if(result.length() > 0) {
406 argument.setValue(result);
407 }
408 else {
409 String args[] = new String[1];
410 args[0] = argument.getName();
411 if(argument.isRequired()) {
412 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
413 }
414 // They've left the field blank
415 else {
416 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
417 argument.setValue(null);
418 }
419 args = null;
420 return false;
421 }
422 argument.setAssigned(true);
423 return true;
424 }
425 return false;
426 }
427 else {
428 argument.setAssigned(false);
429 return true;
430 }
431 }
432
433
434 public boolean updateArgument(boolean checkRequired) {
435
436
437 if (checkRequired){
438 return updateArgument();
439 }
440 else{
441 if (argument.getType() == Argument.STRING){
442 String result = ((JTextField)value_control).getText();
443
444 if(result.length() > 0) {
445 argument.setValue(result);
446 argument.setAssigned(true);
447 }
448 }
449 }
450
451 return true;
452
453 }
454
455
456
457 /** Method to ensure that a certain value is selected, if it exists within that combobox to begin with.
458 * @param combobox The <strong>JComboBox</strong> whose selection we are trying to preset.
459 * @param target The desired value of the selection as a <strong>String</strong>.
460 * @return true if the item was found and selected, false otherwise
461 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.Argument.ArgumentOption
462 */
463 public static boolean selectValue(JComboBox combobox, String target)
464 {
465 for (int i = 0; i < combobox.getItemCount(); i++) {
466 Object object = combobox.getItemAt(i);
467
468 if (object instanceof Argument.ArgumentOption) {
469 Argument.ArgumentOption opt = (Argument.ArgumentOption) object;
470 if (opt.name.startsWith(target)) {
471 combobox.setSelectedIndex(i);
472 combobox.setToolTipText(opt.getToolTip());
473 return true;
474 }
475 }
476 else if (object instanceof MetadataElement) {
477 if(((MetadataElement)object).getFullName().equals(target)) {
478 combobox.setSelectedIndex(i);
479 return true;
480 }
481 }
482 else if (object.toString().equals(target)) {
483 combobox.setSelectedIndex(i);
484 return true;
485 }
486 }
487
488 return false;
489 }
490
491
492 /** Forces the control into an 'enabled' mode. */
493 public void setEnabled() {
494 enabled.setSelected(true);
495 }
496 /** Explicitly sets the value of a JTextField type control to the given String.
497 * @param value_str The new value of the control as a <strong>String</strong>.
498 */
499 public void setValue(String value_str) {
500 ((JTextField)value_control).setText(value_str);
501 }
502
503 /** Listens for actions apon the enable checkbox, and if detected enables or diables control appropriately. */
504 private class EnabledListener
505 implements ActionListener {
506 /** An editor component, such as a JComboBox or JTextField, that might have its enabled state changed by this listener. */
507 private JComponent target = null;
508
509 /** Constructor. */
510 public EnabledListener(JComponent target) {
511 this.target = target;
512 }
513
514 /** Any implementation of ActionListener must include this method so that we can be informed when an action has been performed on or registered check box, prompting us to change the state of the other controls as per the users request.
515 * @param event An <strong>ActionEvent</strong> containing information about the click.
516 */
517 public void actionPerformed(ActionEvent event) {
518 if (this.target == null) {
519 return;
520 }
521 JCheckBox source = (JCheckBox)event.getSource();
522 if(source.isSelected()) {
523 target.setBackground(Color.white);
524 target.setEnabled(true);
525 }
526 else {
527 target.setBackground(Color.lightGray);
528 target.setEnabled(false);
529 }
530 // Special case of stupid JSpinners who don't let their backgrounds change properly.
531 if(target instanceof JSpinner) {
532 JSpinner spinner = (JSpinner) target;
533 JComponent c = spinner.getEditor();
534 if ( c instanceof JSpinner.DefaultEditor ) {
535 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
536 JFormattedTextField field = editor.getTextField();
537 field.setEditable(source.isSelected());
538 if(source.isSelected()) {
539 field.setBackground(Color.white);
540 }
541 else {
542 field.setBackground(Color.lightGray);
543 }
544 }
545 }
546 }
547 }
548
549
550 /** Listener that sets the tooltip associated to a combobox to the tooltip relevant to the selected item. */
551 private class ToolTipUpdater
552 implements ActionListener {
553 /** Any implementation of an ActionListener must include this method so that we can be informed when the selection in a combobox has changed and update the tooltip accordingly.
554 * @param event An <strong>ActionEvent</strong> containing information about the action that fired this call.
555 */
556 public void actionPerformed(ActionEvent event) {
557 JComboBox source = (JComboBox)event.getSource();
558 Object object = source.getSelectedItem();
559 if(object instanceof Argument.ArgumentOption) {
560 Argument.ArgumentOption opt = (Argument.ArgumentOption)object;
561 if(opt != null) {
562 source.setToolTipText(opt.getToolTip());
563 }
564 else {
565 source.setToolTipText(StaticStrings.EMPTY_STR);
566 }
567 }
568 }
569 }
570}
Note: See TracBrowser for help on using the repository browser.