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

Last change on this file since 5210 was 5210, checked in by jmt12, 21 years ago

Fix 203B147

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