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

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

Major CDM rewrite so it uses DOM.

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