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

Last change on this file since 8204 was 8020, checked in by mdewsnip, 20 years ago

Removed some dead code.

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