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

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

2030159: Had confused element name and identifier. Also added ability for ElementWrappers to be stored as Argument values, and thus have identifier appear within GLI while the name is written to the collect.cfg

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