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

Last change on this file since 6770 was 6770, checked in by kjdon, 20 years ago

fixed all the javadoc errors. (hope I didn't commit anything I wasn't supposed to)

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