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

Last change on this file since 10237 was 10237, checked in by mdewsnip, 19 years ago

New code for "incremental" building, by Matthew Whyte.

I've only had time to look at this briefly; I've fixed a few obvious problems but I imagine this will be pretty flaky for a while.

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