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

Last change on this file since 9645 was 9642, checked in by kjdon, 19 years ago

fixed up language type arguments - the list now displays the name not the code, and the existing value will be selected in the list

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