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

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

I believe I have now finished adding tests for missing arguments when configuring a plugin or classifier. I cleared up that weird issue where it would complain about missing an argument, but if you then hit cancel you'd end up with an empty argument anyway.

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