source: trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentConfiguration.java@ 12253

Last change on this file since 12253 was 12252, checked in by kjdon, 18 years ago

ArgumentConfiguration getArguments no longer takes any arguments - there are no such thing as custom args anymore

  • Property svn:keywords set to Author Date Id Revision
File size: 39.1 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29import java.awt.*;
30import java.awt.event.*;
31import java.util.*;
32import javax.swing.*;
33import org.greenstone.gatherer.Configuration;
34import org.greenstone.gatherer.DebugStream;
35import org.greenstone.gatherer.Dictionary;
36import org.greenstone.gatherer.Gatherer;
37import org.greenstone.gatherer.gui.GComboBox;
38import org.greenstone.gatherer.gui.GLIButton;
39import org.greenstone.gatherer.gui.ModalDialog;
40import org.greenstone.gatherer.gui.SimpleMenuBar;
41import org.greenstone.gatherer.metadata.MetadataElement;
42import org.greenstone.gatherer.metadata.MetadataSetManager;
43import org.greenstone.gatherer.metadata.MetadataTools;
44import org.greenstone.gatherer.util.StaticStrings;
45import org.greenstone.gatherer.util.Utility;
46
47/** This class provides us with a dialog box which allows us to edit the arguments of either a Plugin or a Classifier.
48 * @author John Thompson, Greenstone Digital Library, University of Waikato
49 * @version 2.3
50 * @see org.greenstone.gatherer.cdm.Classifier
51 * @see org.greenstone.gatherer.cdm.Plugin
52 */
53public class ArgumentConfiguration
54 extends ModalDialog
55 implements ActionListener {
56 /** The data whose arguments we are editing. */
57 private ArgumentContainer data = null;
58 /** Argument these argument controls coloured or uncoloured (alternates to indicate inheritance). */
59 private boolean coloured = false;
60 /** Whether we have successfully edited the arguments associated with the ArgumentContainer or if we have failed to enter required arguments and have instead cancelled (which would cause argument additions to roll back). */
61 private boolean success = false;
62 /** A button to cancel this dialog. */
63 private JButton cancel = null;
64 /** A button to accept the changes and close the dialog. */
65 private JButton ok = null;
66 /** A reference to the ourselves so our inner classes can dispose us like a dialog. */
67 private ArgumentConfiguration self = null;
68 /** The central pane where a list of known arguments is displayed. */
69 private JPanel central_pane = null;
70 /** The name of the owner of the last argument control. */
71 private String previous_owner = null;
72 /** The size used for an argument label. */
73 static final private Dimension LABEL_SIZE = new Dimension(225, 25);
74 /** Size of a list. */
75 static final private Dimension LIST_SIZE = new Dimension(380, 50);
76 /** The size used for the dialog. */
77 static final private Dimension SIZE = new Dimension(800, 425);
78
79 /** Constructor.
80 * @param data The plugin or classifier whose arguments we are configuring, in the form of its supported <strong>ArgumentContainer</strong> interface.
81 * @see org.greenstone.gatherer.Configuration
82 */
83 public ArgumentConfiguration(ArgumentContainer data) {
84 super(Gatherer.g_man);
85 this.data = data;
86 this.self = this;
87
88 // Create
89 setModal(true);
90 setSize(SIZE);
91 setJMenuBar(new SimpleMenuBar("designingacollection")); // can we tell whether we are doing a classifier or plugin, to make the help more specific??
92 setTitle(Dictionary.get("CDM.ArgumentConfiguration.Title"));
93
94 central_pane = new JPanel();
95 JPanel content_pane = (JPanel) getContentPane();
96
97 JPanel header_pane = new JPanel();
98 JLabel header = new JLabel(Dictionary.get("CDM.ArgumentConfiguration.Header", data.getName()));
99 header.setHorizontalAlignment(JLabel.CENTER);
100 header.setOpaque(true);
101
102 JPanel button_pane = new JPanel();
103 cancel = new GLIButton(Dictionary.get("General.Cancel"), Dictionary.get("General.Pure_Cancel_Tooltip"));
104
105 ok = new GLIButton(Dictionary.get("General.OK"), Dictionary.get("General.OK_Tooltip"));
106
107 // Listeners
108 cancel.addActionListener(this);
109 ok.addActionListener(this);
110 ok.addActionListener(CollectionDesignManager.all_change_listener);
111
112 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
113 button_pane.setLayout(new GridLayout(1,2));
114 button_pane.add(ok);
115 button_pane.add(cancel);
116
117 central_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
118 central_pane.setLayout(new BoxLayout(central_pane, BoxLayout.Y_AXIS));
119
120 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
121 content_pane.setLayout(new BorderLayout());
122 content_pane.add(header, BorderLayout.NORTH);
123 content_pane.add(new JScrollPane(central_pane), BorderLayout.CENTER);
124 content_pane.add(button_pane, BorderLayout.SOUTH);
125
126 // Now generate a set of controls for each of the arguments.
127 generateControls();
128
129 // Display on screen.
130 Dimension screen_size = Configuration.screen_size;
131 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
132 screen_size = null;
133 }
134
135 /** Any implementation of ActionListener must include this method so that we can be informed when an action has occured on one of the controls we are listening to.
136 * @param event An <strong>ActionEvent</strong> containing pertinant information about the event that fired this call.
137 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl
138 * @see org.greenstone.gatherer.cdm.ArgumentContainer
139 */
140 public void actionPerformed(ActionEvent event) {
141 boolean cont = true;
142 if (event.getSource() == ok) {
143 // Clear the current focus to ensure components such as combobox have correctly updated
144 // Loop through each of the controls in the central pane, updating the matching argument as necessary.
145 for(int i = 0; i < central_pane.getComponentCount(); i++) {
146 Component component = central_pane.getComponent(i);
147 if(component instanceof ArgumentControl) {
148 cont = cont && ((ArgumentControl)component).updateArgument();
149 }
150 }
151 if(cont) {
152 success = true;
153 }
154 }
155 if(cont) {
156 dispose();
157 }
158 }
159
160 /** Destructor. */
161 public void destroy() {
162 cancel = null;
163 central_pane = null;
164 //custom_pane = null;
165 //custom = null;
166 data = null;
167 ok = null;
168 self = null;
169 }
170
171 /** Method which actually forces the dialog to be shown on screen.
172 * @return <i>true</i> if the user completed configuration and pressed ok, <i>false</i> otherwise.
173 */
174 public boolean display() {
175 setVisible(true);
176 return success;
177 }
178
179 private void addHeader(String name, Color color) {
180 JPanel header = new JPanel();
181 header.setBackground(color);
182 JPanel inner_pane = new JPanel();
183 inner_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,5,5,5), BorderFactory.createRaisedBevelBorder()));
184 inner_pane.setBackground(color);
185 JLabel header_label = new JLabel("<html><strong>" + name + "</strong></html>");
186 header_label.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
187 header_label.setHorizontalAlignment(JLabel.CENTER);
188 header_label.setOpaque(true);
189
190 // Layout
191 inner_pane.setLayout(new BorderLayout());
192 inner_pane.add(header_label, BorderLayout.CENTER);
193
194 header.setLayout(new BorderLayout());
195 header.add(inner_pane, BorderLayout.CENTER);
196 central_pane.add(header);
197 }
198
199 /** Method to iterate through the arguments associated with whatever argument container we are building an argument control view for, creating the appropriate controls for each.
200 * @see org.greenstone.gatherer.cdm.Argument
201 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl
202 */
203 private void generateControls() {
204 ArrayList arguments = data.getArguments();
205 int total_height = 250;
206 int current_mode = Configuration.getMode();
207 for(int i = 0; i < arguments.size(); i++) {
208 Argument argument = (Argument) arguments.get(i);
209 if(!argument.isHiddenGLI() && (current_mode > Configuration.LIBRARIAN_MODE || !(argument.getType() == Argument.REGEXP))) {
210 ArgumentControl argument_control = new ArgumentControl(argument);
211 total_height = total_height - argument_control.getPreferredSize().height;
212 central_pane.add(argument_control);
213 }
214 }
215 if(total_height > 0) {
216 JPanel filler = new JPanel();
217 filler.setPreferredSize(new Dimension(100, total_height));
218 filler.setSize(new Dimension(100, total_height));
219 central_pane.add(filler);
220 }
221 }
222
223 /** This class encapsulates all the technical difficulty of creating a specific control based on an Argument. */
224 private class ArgumentControl
225 extends JPanel {
226 /** The Argument this control will be based on. */
227 private Argument argument = null;
228
229 private Color colour_one = Configuration.getColor("coloring.collection_heading_background", false);
230 private Color colour_two = Configuration.getColor("coloring.collection_tree_background", false);
231 /** One of a possible two buttons available for adding to this control. */
232 private JButton one = null;
233 /** The second of two buttons available for adding to this control. */
234 private JButton two = null;
235 /** A checkbox to allow enabling or diabling of this Argument. */
236 private JCheckBox enabled = null;
237 /** Some form of editor component, such as a JComboBox or JTextField, used to set parameters to an Argument. */
238 private JComponent value = null;
239 /** Can be used in place of the other editor components if a list is required. */
240 private JList list = null;
241 /** Constructor.
242 * @param argument The <strong>Argument</strong> this control will be built around.
243 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.AddListener
244 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.EnabledListener
245 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.HierarchyListener
246 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.ListOption
247 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.RemoveListener
248 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.ToolTipUpdater
249 */
250 public ArgumentControl(Argument argument) {
251 this.argument = argument;
252 ///ystem.err.println("generating controls for arg "+argument.getName());
253 String tip = "<html>" + argument.getDescription() + "</html>";
254 tip = Utility.formatHTMLWidth(tip, 60);
255
256 // If this is the first control, there is no history.
257 if(previous_owner == null) {
258 ///ystem.err.println("previous owner is null");
259 previous_owner = argument.getOwner();
260 addHeader(previous_owner, colour_two);
261 }
262 // Otherwise if the owner of the control has changed since the last argument, toggle the colouring of the control.
263 else if(previous_owner != argument.getOwner()) {
264 ///ystem.err.println("previous owner is different from current owner");
265 coloured = !coloured;
266 previous_owner = argument.getOwner();
267 addHeader(previous_owner, (coloured ? colour_one : colour_two));
268 }
269 // Create
270 if(coloured) {
271 setBackground(colour_one);
272 }
273 else {
274 setBackground(colour_two);
275 }
276 JLabel owner_label = new JLabel(argument.getOwner());
277 owner_label.setOpaque(false);
278 JLabel label = new JLabel(argument.getName());
279 label.setOpaque(false);
280 label.setPreferredSize(LABEL_SIZE);
281 label.setToolTipText(tip);
282 enabled = new JCheckBox(argument.getName());
283 enabled.setOpaque(false);
284 enabled.setPreferredSize(LABEL_SIZE);
285 enabled.setToolTipText(tip);
286 JPanel inner_pane = new JPanel();
287 inner_pane.setOpaque(false);
288 String existing_value = argument.getValue();
289 String default_value = argument.getDefaultValue();
290
291 switch(argument.getType()) {
292 case Argument.ENUM:
293 // Build an option model, wrapping each entry of the list table.
294 HashMap arg_list = argument.getOptions();
295 ArrayList options_model = new ArrayList();
296 Iterator it = arg_list.keySet().iterator();
297 while(it.hasNext()) {
298 String key = (String) it.next();
299 options_model.add(new ListOption(key, (String)arg_list.get(key)));
300 }
301 Collections.sort(options_model);
302 value = new GComboBox(options_model.toArray(), false);
303 ((JComboBox)value).addActionListener(new ToolTipUpdater());
304 if(existing_value != null && existing_value.length() > 0) {
305 // Select the correct value. Since they're all text strings we better iterate to be safe.
306 selectValue((JComboBox)value, existing_value);
307 }
308 else if(default_value != null) {
309 ///ystem.err.println("Default for argument: " + argument.getName());
310 // Same as above except for default value.
311 selectValue((JComboBox)value, default_value);
312 }
313 break;
314
315 case Argument.FLAG:
316 // Only need the check box.
317 break;
318
319 case Argument.HIERARCHY:
320 // I don't think these are used any more...
321 break;
322
323 case Argument.INTEGER:
324 // Build a spinner
325 int initial_value=0;
326 // If there was an original value, set it.
327 if(existing_value != null && !existing_value.equals("")) {
328 try {
329 initial_value = Integer.parseInt(existing_value);
330 //spinner.setValue(new Integer(existing_value));
331 }
332 catch (Exception error) {
333 DebugStream.println("ArgumentConfiguration Error: "+error);
334 }
335 } else if (default_value != null && !default_value.equals("")) {
336 try {
337 initial_value = Integer.parseInt(default_value);
338 //spinner.setValue(new Integer(default_value));
339 }
340 catch (Exception error) {
341 DebugStream.println("ArgumentConfiguration Error: "+error);
342 }
343 }
344 if (initial_value < argument.getMinimum()) {
345 initial_value = argument.getMinimum();
346 } else if (initial_value > argument.getMaximum()) {
347 initial_value = argument.getMaximum();
348 }
349
350 JSpinner spinner = new JSpinner(new SpinnerNumberModel(initial_value, argument.getMinimum(), argument.getMaximum(), 1));
351
352 // And remember it
353 value = spinner;
354 break;
355
356 case Argument.REGEXP:
357 case Argument.STRING:
358 // If there is already a value set for this argument, use it
359 if (existing_value != null && !existing_value.equals("")) {
360 value = new JTextField(existing_value);
361 break;
362 }
363
364 // Use the default value, if there is one
365 if (default_value != null && !default_value.equals("")) {
366 value = new JTextField(default_value);
367 break;
368 }
369
370// // Special test just for the hfile field.
371// if (argument.getName().equals("hfile")) {
372// // Work through previous controls looking for the metadata one.
373// for (int i = 0; i < central_pane.getComponentCount(); i++) {
374// Object object = central_pane.getComponent(i);
375// if (object instanceof ArgumentControl) {
376// ArgumentControl control = (ArgumentControl) object;
377// if (control.toString().equals("metadata")) {
378// Object temp = control.getValue();
379// if (temp != null) {
380// value = new JTextField(temp.toString() + ".txt");
381// break;
382// }
383// }
384// }
385// }
386// }
387
388 // Blank field
389 value = new JTextField();
390 break;
391
392 case Argument.LANGUAGE:
393 value = new GComboBox(CollectionDesignManager.language_manager.getLanguageCodes().toArray(), false);
394 // we want to display the language name not the code
395 ((JComboBox)value).setRenderer(new LanguageListCellRenderer());
396 // Now ensure we have the existing value or default value selected if either exist in our known languages
397 String lang_name = null;
398 String selected_code = existing_value;
399 if(existing_value != null && !existing_value.equals("")) {
400 lang_name = CollectionDesignManager.language_manager.getLanguageName(existing_value);
401 }
402 if(lang_name == null && default_value != null) {
403 lang_name = CollectionDesignManager.language_manager.getLanguageName(default_value);
404 selected_code = default_value;
405 }
406 if (lang_name != null) {
407 ((JComboBox)value).setSelectedItem(selected_code);
408 }
409 break;
410
411 case Argument.METADATUM:
412 case Argument.METADATA:
413 value = new GComboBox(MetadataSetManager.getEveryMetadataSetElement(), false);
414
415 // Editable for advanced modes (allows things like dc.Title,ex.Title)
416 if (Configuration.getMode() > Configuration.ASSISTANT_MODE) {
417 ((JComboBox) value).setEditable(true);
418 }
419
420 // Now ensure we have the existing value or default value selected if either exist.
421 if (existing_value != null && existing_value.length() > 0) {
422 boolean found = selectValue((JComboBox) value, existing_value);
423 // It's possible that this is a custom value and so doesn't exist in the combobox
424 if (!found) {
425 // If so, add it then select it
426 ((JComboBox) value).addItem(existing_value);
427 ((JComboBox) value).setSelectedItem(existing_value);
428 }
429 }
430 else if (default_value != null) {
431 // if no namespace for default value, add ex.
432 // won't work if we want to set a non-metadata value
433 if (MetadataTools.getMetadataSetNamespace(default_value).equals("")) {
434 default_value = StaticStrings.EXTRACTED_NAMESPACE+default_value;
435 }
436 selectValue((JComboBox) value, default_value);
437 }
438 break;
439
440// ---- Special interface for adding and ordering multiple metadata items ----
441// Turned off at Ian's request!
442// case Argument.METADATA:
443// // Comma separated metadata values.
444// ArrayList values = argument.getValues();
445// value = new GComboBox(MetadataSetManager.getEveryMetadataSetElement(), false);
446// //((JComboBox)value).setEditable(false);
447// DefaultListModel model = new DefaultListModel();
448// list = new JList(model);
449// list.setVisibleRowCount(3);
450// for(int i = 0; i < values.size(); i++) {
451// model.addElement(values.get(i));
452// }
453
454// one = new GLIButton();
455// one.addActionListener(new AddListener((JComboBox)value, list));
456// Dictionary.setBoth(one, "CDM.ArgumentConfiguration.Add", "CDM.ArgumentConfiguration.Add_Tooltip");
457// two = new GLIButton();
458// two.addActionListener(new RemoveListener(list));
459// Dictionary.setBoth(two, "CDM.ArgumentConfiguration.Remove", "CDM.ArgumentConfiguration.Remove_Tooltip");
460
461// if(argument.getValues().size() > 0 || argument.isRequired()) {
462// enabled.setSelected(true);
463// list.setBackground(Color.white);
464// list.setEnabled(true);
465// one.setEnabled(true);
466// two.setEnabled(true);
467// value.setEnabled(true);
468// }
469// else {
470// enabled.setSelected(false);
471// list.setBackground(Color.lightGray);
472// list.setEnabled(false);
473// one.setEnabled(false);
474// two.setEnabled(false);
475// value.setEnabled(false);
476// }
477// break;
478 } // end of switch
479
480 // Enable or disable as necessary.
481 if(argument.isRequired() || argument.isAssigned()) {
482 enabled.setSelected(true);
483 if(value != null) {
484 value.setOpaque(true);
485 value.setBackground(Color.white);
486 value.setEnabled(true);
487 if(value instanceof JSpinner) {
488 // Set enabled
489 JComponent c = ((JSpinner)value).getEditor();
490 if ( c instanceof JSpinner.DefaultEditor ) {
491 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
492 JFormattedTextField field = editor.getTextField();
493 field.setEditable(true);
494 field.setBackground(Color.white);
495 }
496 }
497 }
498 }
499 else {
500 enabled.setSelected(false);
501 if(value != null) {
502 value.setOpaque(true);
503 value.setBackground(Color.lightGray);
504 value.setEnabled(false);
505 if(value instanceof JSpinner) {
506 // Set enabled
507 JComponent c = ((JSpinner)value).getEditor();
508 if ( c instanceof JSpinner.DefaultEditor ) {
509 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
510 JFormattedTextField field = editor.getTextField();
511 field.setEditable(false);
512 field.setBackground(Color.lightGray);
513 }
514 }
515 }
516 }
517 // Listener
518 if(value != null && !argument.isRequired()) {
519 enabled.addActionListener(new EnabledListener(one, two, list, value));
520 }
521
522 // Layout
523 inner_pane.setLayout(new BorderLayout());
524 if (argument.isRequired()) {
525 inner_pane.add(label, BorderLayout.WEST);
526 }
527 else {
528 inner_pane.add(enabled, BorderLayout.WEST);
529 }
530
531 if (list == null) {
532 enabled.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
533 if (value != null) {
534 inner_pane.add(value, BorderLayout.CENTER);
535 }
536 }
537 else {
538 JPanel left_pane = new JPanel(new BorderLayout());
539 left_pane.add(new JLabel(""), BorderLayout.NORTH);
540 left_pane.add(value, BorderLayout.CENTER);
541 left_pane.add(one, BorderLayout.SOUTH);
542 left_pane.setOpaque(false);
543
544 JPanel right_pane = new JPanel(new BorderLayout());
545 right_pane.add(new JScrollPane(list), BorderLayout.CENTER);
546 right_pane.add(two, BorderLayout.SOUTH);
547 right_pane.setOpaque(false);
548
549 JPanel control_pane = new JPanel(new GridLayout(1, 2));
550 control_pane.add(left_pane);
551 control_pane.add(right_pane);
552
553 inner_pane.add(control_pane, BorderLayout.CENTER);
554 }
555
556 setLayout(new BorderLayout());
557 add(inner_pane, BorderLayout.CENTER);
558 }
559
560 public Argument getArgument() {
561 return argument;
562 }
563
564 public Object getValue() {
565 if(value instanceof JComboBox) {
566 return ((JComboBox)value).getSelectedItem();
567 }
568 else if(value instanceof JTextField) {
569 return ((JTextField)value).getText();
570 }
571 return null;
572 }
573 /** Identifies this control by returning the name of the Argument it is based on.
574 * @return The name of the Argument as a <strong>String</strong>.
575 * @see org.greenstone.gatherer.cdm.Argument
576 */
577 public String toString() {
578 return argument.getName();
579 }
580 /** Updates the enwrapped Argument using the values provided by the controls.
581 * @return <i>true</i> if the update was successful, <i>false</i> otherwise.
582 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.ListOption
583 * @see org.greenstone.gatherer.cdm.Language
584 */
585 public boolean updateArgument() {
586 if(enabled.isSelected() || argument.isRequired()) {
587 argument.setAssigned(false);
588 String result = null;
589 switch(argument.getType()) {
590 case Argument.ENUM:
591 ListOption option = (ListOption)((JComboBox)value).getSelectedItem();
592 if(option != null && option.getValue().length() > 0) {
593 argument.setValue(option.getValue());
594 }
595 else {
596 String args[] = new String[1];
597 args[0] = argument.getName();
598 if(argument.isRequired()) {
599 JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
600 }
601 // They've left the field blank
602 else {
603 JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
604 argument.setValue(null);
605 }
606 args = null;
607 return false;
608 }
609 argument.setAssigned(true);
610 return true;
611 case Argument.FLAG:
612 // Should have already been handled above.
613 argument.setAssigned(true);
614 return true;
615 case Argument.INTEGER:
616 result = ((JSpinner)value).getValue().toString();
617 if(result.length() > 0) {
618 // Test if the value entered is a valid int.
619 try {
620 int x = Integer.parseInt(result);
621 }
622 catch(NumberFormatException nfe) {
623 String args[] = new String[2];
624 args[0] = argument.getName();
625 args[1] = result;
626 JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.Bad_Integer", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
627 args = null;
628 return false;
629 }
630 argument.setValue(result);
631 }
632 else {
633 String args[] = new String[1];
634 args[0] = argument.getName();
635 if(argument.isRequired()) {
636 JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
637 }
638 // They've left the field blank
639 else {
640 JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
641 argument.setValue(null);
642 }
643 args = null;
644 return false;
645 }
646 argument.setAssigned(true);
647 return true;
648 case Argument.LANGUAGE:
649 String language = (((JComboBox)value).getSelectedItem()).toString();
650 argument.setValue(language);
651 // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
652 argument.setAssigned(true);
653 return true;
654 case Argument.METADATUM:
655 case Argument.METADATA:
656 Object new_value_raw = ((JComboBox) value).getSelectedItem();
657 if (new_value_raw instanceof MetadataElement) {
658 argument.setValue(((MetadataElement) new_value_raw).getFullName());
659 }
660 else {
661 // But we have to be careful as an arbitary string object could be zero length
662 String new_value = new_value_raw.toString();
663 ///ystem.err.println("The current value is: " + new_value);
664 if(new_value.length() > 0) {
665 argument.setValue(new_value);
666 }
667 else {
668 String args[] = new String[1];
669 args[0] = argument.getName();
670 if(argument.isRequired()) {
671 JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
672 }
673 // They've left the field blank
674 else {
675 JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
676 argument.setValue(null);
677 }
678 args = null;
679 return false;
680 }
681 }
682 argument.setAssigned(true);
683 return true;
684// case Argument.METADATA:
685// DefaultListModel model = (DefaultListModel)list.getModel();
686// ArrayList values = new ArrayList();
687// for(int i = 0; i < model.size(); i++) {
688// values.add(model.get(i));
689// }
690// argument.setValues(values);
691// argument.setAssigned(true);
692// return true;
693 case Argument.HIERARCHY:
694// argument.setValue(((JComboBox)value).getSelectedItem().toString());
695// // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
696// argument.setAssigned(true);
697 return true;
698 case Argument.REGEXP:
699 case Argument.STRING:
700 result = ((JTextField)value).getText();
701 if(result.length() > 0) {
702 argument.setValue(result);
703 }
704 else {
705 String args[] = new String[1];
706 args[0] = argument.getName();
707 if(argument.isRequired()) {
708 JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
709 }
710 // They've left the field blank
711 else {
712 JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
713 argument.setValue(null);
714 }
715 args = null;
716 return false;
717 }
718 argument.setAssigned(true);
719 return true;
720 }
721 return false;
722 }
723 else {
724 argument.setAssigned(false);
725 return true;
726 }
727 }
728 /** Method to ensure that a certain value is selected, if it exists within that combobox to begin with.
729 * @param combobox The <strong>JComboBox</strong> whose selection we are trying to preset.
730 * @param target The desired value of the selection as a <strong>String</strong>.
731 * @return true if the item was found and selected, false otherwise
732 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.ListOption
733 */
734 public boolean selectValue(JComboBox combobox, String target) {
735 ///ystem.err.println("Searching for the target string: " + target);
736 for(int i = 0; i < combobox.getItemCount(); i++) {
737 Object object = combobox.getItemAt(i);
738 if(object instanceof ListOption) {
739 ListOption lo = (ListOption) object;
740 ///ystem.err.print("/tChecking: " + lo.getValue() + "... ");
741 if(lo.getValue().startsWith(target)) {
742 ///ystem.err.println("Match!");
743 combobox.setSelectedIndex(i);
744 return true;
745 }
746 /*
747 else {
748 System.err.println("No Match.");
749 }
750 */
751 }
752 else if (object instanceof MetadataElement) {
753 if(object.toString().equals(target)) {
754 combobox.setSelectedIndex(i);
755 return true;
756 }
757 }
758 }
759 return false;
760 }
761 /** Forces the control into an 'enabled' mode. */
762 public void setEnabled() {
763 enabled.setSelected(true);
764 }
765 /** Explicitly sets the value of a JTextField type control to the given String.
766 * @param value_str The new value of the control as a <strong>String</strong>.
767 */
768 public void setValue(String value_str) {
769 ((JTextField)value).setText(value_str);
770 }
771// /** Listener which adds entries to a list from a combobox when fired. */
772// private class AddListener
773// implements ActionListener {
774// /** The model behind the target list. */
775// private DefaultListModel model = null;
776// /** The source for data to be added to the list. */
777// private JComboBox source = null;
778// /** The list to add data to. */
779// private JList target = null;
780// /** Constructor.
781// * @param source A <strong>JComboBox</strong> which serves as the source for data.
782// * @param target A <strong>JList</strong> which serves as the target for data.
783// */
784// public AddListener(JComboBox source, JList target) {
785// this.model = (DefaultListModel) target.getModel();
786// this.source = source;
787// this.target = target;
788// }
789// /** When the add button is clicked, we attempt to add the selected metadata from the source into the target.
790// * @param event An <strong>ActionEvent</strong> containing information about the event.
791// */
792// public void actionPerformed(ActionEvent event) {
793// ElementWrapper element = (ElementWrapper) source.getSelectedItem();
794// String name = element.toString();
795// if (!model.contains(name)) {
796// model.addElement(name);
797// }
798// }
799// }
800 /** Listens for actions apon the enable checkbox, and if detected enables or diables control appropriately. */
801 private class EnabledListener
802 implements ActionListener {
803 /** One of two possible buttons that might have their enabled state changed by this listener. */
804 private JButton one = null;
805 /** One of two possible buttons that might have their enabled state changed by this listener. */
806 private JButton two = null;
807 /** An editor component, such as a JComboBox or JTextField, that might have its enabled state changed by this listener. */
808 private JComponent target = null;
809 /** A list which might have its enabled state changed by this listener. */
810 private JList list = null;
811 /** Constructor.
812 * @param one A <strong>JButton</strong> whose enabled state is determined by the listener, or <i>null</i> if no button.
813 * @param two A <strong>JButton</strong> whose enabled state is determined by the listener, or <i>null</i> if no button.
814 * @param list A <strong>JList</strong> whose enabled state is determined by the listener, or <i>null</i> if no list.
815 * @param target A <strong>JComponent</strong> whose enabled state is determined by the listener, or <i>null</i> if no component.
816 */
817 public EnabledListener(JButton one, JButton two, JList list, JComponent target) {
818 this.list = list;
819 this.one = one;
820 this.target = target;
821 this.two = two;
822 }
823 /** 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.
824 * @param event An <strong>ActionEvent</strong> containing information about the click.
825 */
826 public void actionPerformed(ActionEvent event) {
827 JCheckBox source = (JCheckBox)event.getSource();
828 if(source.isSelected()) {
829 target.setBackground(Color.white);
830 target.setEnabled(true);
831 if(target instanceof JSpinner) {
832 // Set enabled
833 JComponent c = ((JSpinner)target).getEditor();
834 if ( c instanceof JSpinner.DefaultEditor ) {
835 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
836 JFormattedTextField field = editor.getTextField();
837 field.setEditable(true);
838 field.setBackground(Color.white);
839 }
840 }
841 if(one != null && two != null && list != null) {
842 one.setEnabled(true);
843 two.setEnabled(true);
844 list.setBackground(Color.white);
845 list.setEnabled(true);
846 }
847 }
848 else {
849 target.setBackground(Color.lightGray);
850 target.setEnabled(false);
851 if(target instanceof JSpinner) {
852 // Set enabled
853 JComponent c = ((JSpinner)target).getEditor();
854 if ( c instanceof JSpinner.DefaultEditor ) {
855 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
856 JFormattedTextField field = editor.getTextField();
857 field.setEditable(false);
858 field.setBackground(Color.lightGray);
859 }
860 }
861 if(one != null && two != null && list != null) {
862 one.setEnabled(false);
863 two.setEnabled(false);
864 list.setBackground(Color.lightGray);
865 list.setEnabled(false);
866 }
867 }
868 }
869 }
870 /** If a metadata element is selected that requires an hfile, then this listener defaults that hfile. */
871// private class HierarchyListener
872// implements ItemListener {
873// /** Any implementation of ItemListener must include this method so that we can be informed when an item from the list is selected, and generate a predetermined hfile for that selection.
874// * @param event An <strong>ItemEvent</strong> containing information about the selection.
875// * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl
876// */
877// public void itemStateChanged(ItemEvent event) {
878// // Determine if the selected element represents a hierarchy.
879// Object temp = ((JComboBox)value).getSelectedItem();
880// String filename = temp.toString();
881// // Search for a argument control called hfile and enable and set value.
882// for(int i = 0; i < central_pane.getComponentCount(); i++) {
883// Object object = central_pane.getComponent(i);
884// if(object instanceof ArgumentControl) {
885// ArgumentControl control = (ArgumentControl) object;
886// if(control.toString().equals("hfile")) {
887// control.setValue(filename + ".txt");
888// control.setEnabled(true);
889// }
890// }
891// }
892// }
893// }
894 /** A ListOption is a compound item which is constructed from several Strings. That magic part is that the length of screen real-estate used by the text version of this item is limited. */
895 private class ListOption
896 implements Comparable {
897 /** The maximum length of this String version of this item. */
898 private int MAX_DESC = 65;
899 /** The description of the value for this item. */
900 private String description = null;
901 /** A cached value for the text value of this option, as it never changes after the first call to toString(). */
902 private String text = null;
903 /** The value for this item. */
904 private String value = null;
905 /** Constructor.
906 * @param value The value for this item as a <strong>String</strong>.
907 * @param description The description of the value as a <strong>String</strong>.
908 */
909 public ListOption(String value, String description) {
910 this.description = description;
911 this.value = value;
912 }
913 /** Compare two possible ListOption objects for ordering.
914 * @param object The <strong>Object</strong> to compare to.
915 * @return An <i>int</i> indicating order as explained in String.
916 * @see java.lang.String#compareTo
917 */
918 public int compareTo(Object object) {
919 return toString().compareTo(object.toString());
920 }
921 /** Tests two possible ListOption objects for equality. Uses the result from compareTo().
922 * @param object The <strong>Object</strong> which may be equal.
923 * @return <i>true</i> if the objects are equal, <i>false</i> otherwise.
924 */
925 public boolean equals(Object object) {
926 return (object != null && compareTo(object) == 0);
927 }
928 /** Retrieve the description of this list item.
929 * @return The description as a <strong>String</strong>.
930 */
931 public String getDesc() {
932 return description;
933 }
934 /** Retrieve the value of this list item.
935 * @return The value as a <strong>String</strong>.
936 */
937 public String getValue() {
938 return value;
939 }
940 /** Convert this object into a nice readable String.
941 * @return A <strong>String</strong> representing this object.
942 */
943 public String toString() {
944 if(text == null) {
945 if(description.length() >= MAX_DESC) {
946 text = value + " "+ StaticStrings.MINUS_CHARACTER + " "+ description.substring(0, MAX_DESC) + StaticStrings.TRUNCATED_STRING;
947 }
948 else {
949 text = value + " "+ StaticStrings.MINUS_CHARACTER + " "+ description;
950 }
951 }
952 return text;
953 }
954 }
955 /** Listener which removes entries from a list from a combobox when fired. */
956 private class RemoveListener
957 implements ActionListener {
958 /** The model behind the target list. */
959 private DefaultListModel model = null;
960 /** The list to remove data from. */
961 private JList target = null;
962 /** Constructor.
963 * @param target A <strong>JList</strong>.
964 */
965 public RemoveListener(JList target) {
966 this.model = (DefaultListModel) target.getModel();
967 this.target = target;
968 }
969 /** When the remove button is clicked, we attempt to remove the selected metadata from the target.
970 * @param event An <strong>ActionEvent</strong> containing information about the event.
971 */
972 public void actionPerformed(ActionEvent event) {
973 if(!target.isSelectionEmpty()) {
974 int index = target.getSelectedIndex();
975 model.remove(index);
976 }
977 }
978 }
979 /** Listener that sets the tooltip associated to a combobox to the tooltip relevant to the selected item. */
980 private class ToolTipUpdater
981 implements ActionListener {
982 /** 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.
983 * @param event An <strong>ActionEvent</strong> containing information about the action that fired this call.
984 */
985 public void actionPerformed(ActionEvent event) {
986 JComboBox source = (JComboBox)event.getSource();
987 Object object = source.getSelectedItem();
988 if(object instanceof ListOption) {
989 ListOption lo = (ListOption)object;
990 if(lo != null) {
991 String description = Utility.formatHTMLWidth(lo.getDesc(), 60);
992 source.setToolTipText(description);
993 }
994 else {
995 source.setToolTipText(StaticStrings.EMPTY_STR);
996 }
997 }
998 }
999 }
1000 }
1001}
Note: See TracBrowser for help on using the repository browser.