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

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

removed some unused variables

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