source: debug-testing/gli-ctrlC-issue/ArgumentControl.java@ 31736

Last change on this file since 31736 was 31736, checked in by ak19, 7 years ago

Creating a folder to add files that are in a convenient state for debugging problems we haven't resolved yet. And adding files for debugging the issue of launching GLI from DOS, but Ctrl-C being ineffective until you exit GLI, which is when the Ctrl-C finally registers.

File size: 21.9 KB
Line 
1package org.greenstone.gatherer.cdm;
2
3import java.awt.*;
4import java.awt.event.*;
5import javax.swing.*;
6import javax.swing.event.*;
7
8import java.io.File;
9import java.util.ArrayList;
10import java.util.Collections;
11import java.util.Map;
12import java.util.Iterator;
13
14import org.greenstone.gatherer.Configuration;
15import org.greenstone.gatherer.DebugStream;
16import org.greenstone.gatherer.Dictionary;
17import org.greenstone.gatherer.Gatherer;
18import org.greenstone.gatherer.gui.GComboBox;
19import org.greenstone.gatherer.util.StaticStrings;
20import org.greenstone.gatherer.util.Utility;
21import org.greenstone.gatherer.metadata.MetadataElement;
22import org.greenstone.gatherer.metadata.MetadataSet;
23import org.greenstone.gatherer.metadata.MetadataSetManager;
24import org.greenstone.gatherer.metadata.MetadataTools;
25
26/** This class encapsulates all the technical difficulty of creating a specific control based on an Argument. */
27public class ArgumentControl
28 extends JPanel {
29
30 static protected Dimension LABEL_SIZE = new Dimension(175, 25);
31 static protected Dimension ROW_SIZE = new Dimension(400, 30);
32 /** The Argument this control will be based on. */
33 private Argument argument = null;
34
35 /** A checkbox to allow enabling or diabling of this Argument. */
36 private JCheckBox enabled = null;
37 /** Some form of editor component, such as a JComboBox or JTextField, used to set parameters to an Argument. */
38 private JComponent value_control = null;
39
40 /** Constructor.
41 */
42 public ArgumentControl(Argument argument, boolean is_enabled, String preset_value) {
43 this.setComponentOrientation(Dictionary.getOrientation());
44 this.argument = argument;
45
46 String tip = "<html>" + argument.getName()+": "+argument.getDescription() + "</html>";
47 tip = Utility.formatHTMLWidth(tip, 80);
48
49 setBackground(Configuration.getColor("coloring.collection_tree_background", false));
50 setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
51 setLayout(new BorderLayout());
52 setPreferredSize(ROW_SIZE);
53
54 // display the name set in the disp option if there is one
55 // otherwise display name option value instead
56 String dispName = argument.getDisplayName();
57 if(dispName.equals("")){
58 dispName = argument.getName();
59 }
60
61 if (argument.isRequired()) {
62 //JLabel label = new JLabel(argument.getName());
63 JLabel label = new JLabel(dispName);
64 label.setComponentOrientation(Dictionary.getOrientation());
65 label.setOpaque(false);
66 label.setPreferredSize(LABEL_SIZE);
67 label.setToolTipText(tip);
68 add(label, BorderLayout.LINE_START);
69 } else {
70 //enabled = new JCheckBox(argument.getName());
71 enabled = new JCheckBox(dispName);
72 enabled.setComponentOrientation(Dictionary.getOrientation());
73 enabled.setOpaque(false);
74 enabled.setPreferredSize(LABEL_SIZE);
75 enabled.setToolTipText(tip);
76 add(enabled, BorderLayout.LINE_START);
77 }
78
79 String initial_value;
80 if (preset_value != null && !preset_value.equals("")) {
81 initial_value = preset_value;
82 }
83 else {
84 initial_value = argument.getValue();
85 }
86 if (initial_value == null || initial_value.equals("")) {
87 initial_value = argument.getDefaultValue();
88 }
89 if (initial_value == null) {
90 initial_value = "";
91 }
92
93 switch(argument.getType()) {
94 case Argument.ENUM_STRING:
95 case Argument.ENUM:
96 ArrayList option_list = argument.getOptions();
97 boolean editable = false;
98 if (argument.getType() == Argument.ENUM_STRING) {
99 editable = true;
100 }
101 value_control = new GComboBox(option_list.toArray(), editable, false);
102 value_control.setComponentOrientation(Dictionary.getOrientation());
103
104 boolean found = selectValue((JComboBox)value_control, initial_value); // also sets the tooltip
105 if (!found && argument.getType() == Argument.ENUM_STRING) {
106 // Its a custom item
107 ((JComboBox) value_control).addItem(initial_value);
108 ((JComboBox) value_control).setSelectedItem(initial_value);
109 }
110
111 ((JComboBox)value_control).addActionListener(new ToolTipUpdater());
112 break;
113
114 case Argument.FLAG:
115 // Only need the check box.
116 break;
117
118 case Argument.INTEGER:
119 // Build a spinner
120 int initial_int=0;
121 // If there was an original value, set it.
122 try {
123 initial_int = Integer.parseInt(initial_value);
124 } catch (Exception error) {
125 DebugStream.println("ArgumentControl Error: "+error);
126 }
127 if (initial_int < argument.getMinimum()) {
128 initial_int = argument.getMinimum();
129 } else if (initial_int > argument.getMaximum()) {
130 initial_int = argument.getMaximum();
131 }
132
133 JSpinner spinner = new JSpinner(new SpinnerNumberModel(initial_int, argument.getMinimum(), argument.getMaximum(), 1));
134 spinner.setComponentOrientation(Dictionary.getOrientation());
135 // And remember it
136 value_control = spinner;
137 break;
138
139 case Argument.REGEXP:
140 case Argument.STRING:
141 value_control = new JTextField(initial_value);
142 value_control.setComponentOrientation(Dictionary.getOrientation());
143 break;
144
145 case Argument.LANGUAGE:
146 value_control = new GComboBox(CollectionDesignManager.language_manager.getLanguageCodes().toArray(), false);
147 value_control.setComponentOrientation(Dictionary.getOrientation());
148 // we want to display the language name not the code
149 ((JComboBox)value_control).setRenderer(new LanguageListCellRenderer());
150 // Now ensure we have the existing value or default value selected if either exist in our known languages
151 String lang_name = CollectionDesignManager.language_manager.getLanguageName(initial_value);
152 if (lang_name != null) {
153 ((JComboBox)value_control).setSelectedItem(initial_value);
154 }
155 break;
156
157 case Argument.METADATA:
158 value_control = new GComboBox(MetadataSetManager.getEveryMetadataSetElement(), false);
159 value_control.setComponentOrientation(Dictionary.getOrientation());
160 // Editable for advanced modes (allows things like dc.Title,ex.Title)
161 if (Configuration.getMode() > Configuration.ASSISTANT_MODE) {
162 ((JComboBox) value_control).setEditable(true);
163 }
164 // Now ensure we have the existing value or default value selected if either exist.
165 String existing_value = preset_value;
166 if (existing_value == null || existing_value.equals("")) {
167 existing_value = argument.getValue();
168 }
169 if (existing_value == null || existing_value.equals("")) {
170 // try default value
171 String default_value = argument.getDefaultValue();
172 if (default_value != null) {
173 // if no namespace for default value, add ex.
174 // won't work if we want to set a non-metadata value
175 if (MetadataTools.getMetadataSetNamespace(default_value).equals("")) {
176 default_value = StaticStrings.EXTRACTED_NAMESPACE+default_value;
177 }
178 existing_value = default_value;
179 }
180 }
181
182 if (existing_value != null && !existing_value.equals("")) {
183
184 found = selectValue((JComboBox) value_control, existing_value);
185 // It's possible that this is a custom value and so doesn't exist in the combobox
186 if (!found) {
187 // If so, add it then select it
188 ((JComboBox) value_control).addItem(existing_value);
189 ((JComboBox) value_control).setSelectedItem(existing_value);
190 }
191 }
192 break;
193
194 case Argument.METADATA_SET_NAMESPACE:
195 value_control = new JComboBox();
196 value_control.setComponentOrientation(Dictionary.getOrientation());
197 // !! Hack for exploding metadata databases: add the (empty) exploded metadata set
198 File exploded_metadata_set_file = new File(Gatherer.getGLIMetadataDirectoryPath() + "exp" + StaticStrings.METADATA_SET_EXTENSION);
199 MetadataSet exploded_metadata_set = new MetadataSet(exploded_metadata_set_file);
200 Gatherer.c_man.importMetadataSet(exploded_metadata_set);
201
202 // All the loaded metadata sets except the extracted metadata set are applicable
203 ArrayList metadata_sets = MetadataSetManager.getMetadataSets();
204 for (int i = metadata_sets.size() - 1; i >= 0; i--) {
205 MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
206 if (!(metadata_set.getNamespace().equals(MetadataSetManager.EXTRACTED_METADATA_NAMESPACE))) {
207 ((JComboBox)value_control).addItem(metadata_set);
208 }
209 }
210
211 selectValue((JComboBox) value_control, initial_value);
212
213 } // end of switch
214
215 // Enable or disable as necessary.
216 if(argument.isRequired() || argument.isAssigned() || is_enabled) {
217 if (enabled != null) {
218 enabled.setSelected(true);
219 }
220 if(value_control != null) {
221 value_control.setOpaque(true);
222 value_control.setBackground(Color.white);
223 value_control.setEnabled(true);
224 if(value_control instanceof JSpinner) {
225 // Set enabled
226 JComponent c = ((JSpinner)value_control).getEditor();
227 if ( c instanceof JSpinner.DefaultEditor ) {
228 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
229 JFormattedTextField field = editor.getTextField();
230 field.setEditable(true);
231 field.setBackground(Color.white);
232 }
233 }
234 }
235 }
236 else {
237 if (enabled != null) {
238 enabled.setSelected(false);
239 }
240 if(value_control != null) {
241 value_control.setOpaque(true);
242 value_control.setBackground(Color.lightGray);
243 value_control.setEnabled(false);
244 if(value_control instanceof JSpinner) {
245 // Set enabled
246 JComponent c = ((JSpinner)value_control).getEditor();
247 if ( c instanceof JSpinner.DefaultEditor ) {
248 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
249 JFormattedTextField field = editor.getTextField();
250 field.setEditable(false);
251 field.setBackground(Color.lightGray);
252 }
253 }
254 }
255 }
256
257 // Listener
258 if(value_control != null) {
259 if (argument.getType() != Argument.ENUM && argument.getType() != Argument.ENUM_STRING) {
260 // enums have already set tooltips based on option value
261 value_control.setToolTipText(tip);
262 }
263 add(value_control, BorderLayout.CENTER);
264 if (!argument.isRequired()) {
265 //enabled.addActionListener(new EnabledListener(value_control));
266 }
267 }
268 }
269
270 public Argument getArgument() {
271 return argument;
272 }
273
274 public String getArgumentName() {
275 return argument.getName();
276 }
277
278 public String getValue() {
279 if(value_control == null) {
280 return null;
281 }
282 if (value_control instanceof JSpinner) {
283 return ((JSpinner)value_control).getValue().toString();
284 }
285 if(value_control instanceof JComboBox) {
286 Object selected_item = ((JComboBox)value_control).getSelectedItem();
287 if (selected_item != null) {
288 if (argument.getType() == Argument.METADATA_SET_NAMESPACE) {
289 return ((MetadataSet) selected_item).getNamespace();
290 }
291 if (selected_item instanceof Argument.ArgumentOption) {
292 return ((Argument.ArgumentOption)selected_item).name;
293 }
294 if (selected_item instanceof MetadataElement) {
295 return ((MetadataElement) selected_item).getFullName();
296 }
297 return selected_item.toString();
298 }
299 return null;
300 }
301 if(value_control instanceof JTextField) {
302 return ((JTextField)value_control).getText();
303 }
304 return null;
305 }
306 /** Retrieve the control used for storing values.
307 * @return JComponent
308 */
309 public JComponent getValueControl() {
310 return value_control;
311 }
312
313 public boolean isEnabled() {
314 if (enabled == null) {
315 return true; // always enabled
316 }
317 return enabled.isSelected();
318 }
319
320 /// START DEBUG
321 public String getType() {
322
323 if(value_control == null) {
324 return "null";
325 }
326
327 String cName = "";
328 if (value_control instanceof JSpinner) {
329 cName = "JSpinner";
330 }
331 else if(value_control instanceof JComboBox) {
332 Object selected_item = ((JComboBox)value_control).getSelectedItem();
333 cName = "JComboBox";
334 if (selected_item != null) {
335 if (argument.getType() == Argument.METADATA_SET_NAMESPACE) {
336 cName += " - MetadataSet";
337 }
338 if (selected_item instanceof Argument.ArgumentOption) {
339 cName += " - Argument.ArgumentOption";
340 }
341 if (selected_item instanceof MetadataElement) {
342 cName += " - MetadataElement";
343 }
344 cName += " - String";
345 }
346 cName = "";
347 }
348 else if(value_control instanceof JTextField) {
349 cName = "JTextField";
350 }
351 return cName;
352
353 }
354 /// END DEBUG
355
356 /** Identifies this control by returning the name of the Argument it is based on.
357 * @return The name of the Argument as a <strong>String</strong>.
358 * @see org.greenstone.gatherer.cdm.Argument
359 */
360 public String toString() {
361 return argument.getName();
362 }
363 /** Updates the enwrapped Argument using the values provided by the controls.
364 * @return <i>true</i> if the update was successful, <i>false</i> otherwise.
365 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.Argument.ArgumentOption
366 * @see org.greenstone.gatherer.cdm.Language
367 */
368 public boolean updateArgument() {
369 if(argument.isRequired() || enabled.isSelected() ) {
370 argument.setAssigned(false);
371 String result = null;
372 switch(argument.getType()) {
373 case Argument.ENUM:
374 Argument.ArgumentOption option = (Argument.ArgumentOption)((JComboBox)value_control).getSelectedItem();
375 // its impossible not to choose an entry
376 argument.setValue(option.name);
377 argument.setAssigned(true);
378 return true;
379 case Argument.ENUM_STRING:
380 Object new_value_raw = ((JComboBox)value_control).getSelectedItem();
381 if (new_value_raw instanceof Argument.ArgumentOption) {
382 argument.setValue(((Argument.ArgumentOption)new_value_raw).name);
383 } else {
384 // have entered a new string
385 String new_value = new_value_raw.toString();
386 if (new_value.length() > 0) {
387 argument.setValue(new_value);
388 }
389 else {
390 String args[] = new String[1];
391 args[0] = argument.getName();
392 if(argument.isRequired()) {
393 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
394 }
395 // They've left the field blank
396 else {
397 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
398 argument.setValue(null);
399 }
400 args = null;
401 return false;
402 }
403 }
404 argument.setAssigned(true);
405 return true;
406 case Argument.FLAG:
407 // Should have already been handled above.
408 argument.setAssigned(true);
409 return true;
410 case Argument.INTEGER:
411 result = ((JSpinner)value_control).getValue().toString();
412 if(result.length() > 0) {
413 // Test if the value entered is a valid int.
414 try {
415 int x = Integer.parseInt(result);
416 }
417 catch(NumberFormatException nfe) {
418 String args[] = new String[2];
419 args[0] = argument.getName();
420 args[1] = result;
421 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Bad_Integer", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
422 args = null;
423 return false;
424 }
425 argument.setValue(result);
426 }
427 else {
428 String args[] = new String[1];
429 args[0] = argument.getName();
430 if(argument.isRequired()) {
431 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
432 }
433 // They've left the field blank
434 else {
435 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
436 argument.setValue(null);
437 }
438 args = null;
439 return false;
440 }
441 argument.setAssigned(true);
442 return true;
443 case Argument.LANGUAGE:
444 String language = (((JComboBox)value_control).getSelectedItem()).toString();
445 argument.setValue(language);
446 // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
447 argument.setAssigned(true);
448 return true;
449 case Argument.METADATA:
450 String meta_value = (((JComboBox)value_control).getSelectedItem()).toString();
451 if(meta_value.length() > 0) {
452
453 argument.setValue(meta_value);
454 }
455 else {
456 String args[] = new String[1];
457 args[0] = argument.getName();
458 if(argument.isRequired()) {
459 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
460 }
461 // They've left the field blank
462 else {
463 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
464 argument.setValue(null);
465 }
466 args = null;
467 return false;
468 }
469
470 argument.setAssigned(true);
471 return true;
472 case Argument.REGEXP:
473 case Argument.STRING:
474 result = ((JTextField)value_control).getText();
475 if(result.length() > 0) {
476 argument.setValue(result);
477 }
478 else {
479 String args[] = new String[1];
480 args[0] = argument.getName();
481 if(argument.isRequired()) {
482 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
483 }
484 // They've left the field blank
485 else {
486 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
487 argument.setValue(null);
488 }
489 args = null;
490 return false;
491 }
492 argument.setAssigned(true);
493 return true;
494 }
495 return false;
496 }
497 else {
498 argument.setAssigned(false);
499 return true;
500 }
501 }
502
503
504 public boolean updateArgument(boolean checkRequired) {
505
506
507 if (checkRequired){
508 return updateArgument();
509 }
510 else{
511 if (argument.getType() == Argument.STRING){
512 String result = ((JTextField)value_control).getText();
513
514 if(result.length() > 0) {
515 argument.setValue(result);
516 argument.setAssigned(true);
517 }
518 }
519 }
520
521 return true;
522
523 }
524
525
526
527 /** Method to ensure that a certain value is selected, if it exists within that combobox to begin with.
528 * @param combobox The <strong>JComboBox</strong> whose selection we are trying to preset.
529 * @param target The desired value of the selection as a <strong>String</strong>.
530 * @return true if the item was found and selected, false otherwise
531 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.Argument.ArgumentOption
532 */
533 public static boolean selectValue(JComboBox combobox, String target)
534 {
535 for (int i = 0; i < combobox.getItemCount(); i++) {
536 Object object = combobox.getItemAt(i);
537
538 if (object instanceof Argument.ArgumentOption) {
539 Argument.ArgumentOption opt = (Argument.ArgumentOption) object;
540 if (opt.name.startsWith(target)) {
541 combobox.setSelectedIndex(i);
542 combobox.setToolTipText(opt.getToolTip());
543 return true;
544 }
545 }
546 else if (object instanceof MetadataElement) {
547 if(((MetadataElement)object).getFullName().equals(target)) {
548 combobox.setSelectedIndex(i);
549 return true;
550 }
551 }
552 else if (object.toString().equals(target)) {
553 combobox.setSelectedIndex(i);
554 return true;
555 }
556 }
557
558 return false;
559 }
560
561
562 /** Forces the control into an 'enabled' mode. */
563 public void setEnabled() {
564 enabled.setSelected(true);
565 }
566 /** Explicitly sets the value of a JTextField type control to the given String.
567 * @param value_str The new value of the control as a <strong>String</strong>.
568 */
569 public void setValue(String value_str) {
570 ((JTextField)value_control).setText(value_str);
571 }
572
573 /** Listens for actions upon the enable checkbox, and if detected enables or disables control appropriately. */
574 private class EnabledListener
575 implements ActionListener {
576 /** An editor component, such as a JComboBox or JTextField, that might have its enabled state changed by this listener. */
577 private JComponent target = null;
578
579 /** Constructor. */
580 public EnabledListener(JComponent target) {
581 this.target = target;
582 }
583
584 /** 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.
585 * @param event An <strong>ActionEvent</strong> containing information about the click.
586 */
587 public void actionPerformed(ActionEvent event) {
588 if (this.target == null) {
589 return;
590 }
591 JCheckBox source = (JCheckBox)event.getSource();
592 if(source.isSelected()) {
593 target.setBackground(Color.white);
594 target.setEnabled(true);
595 }
596 else {
597 target.setBackground(Color.lightGray);
598 target.setEnabled(false);
599 }
600 // Special case of stupid JSpinners who don't let their backgrounds change properly.
601 if(target instanceof JSpinner) {
602 JSpinner spinner = (JSpinner) target;
603 JComponent c = spinner.getEditor();
604 if ( c instanceof JSpinner.DefaultEditor ) {
605 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
606 JFormattedTextField field = editor.getTextField();
607 field.setEditable(source.isSelected());
608 if(source.isSelected()) {
609 field.setBackground(Color.white);
610 }
611 else {
612 field.setBackground(Color.lightGray);
613 }
614 }
615 }
616 }
617 }
618
619
620 /** Listener that sets the tooltip associated to a combobox to the tooltip relevant to the selected item. */
621 private class ToolTipUpdater
622 implements ActionListener {
623 /** 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.
624 * @param event An <strong>ActionEvent</strong> containing information about the action that fired this call.
625 */
626 public void actionPerformed(ActionEvent event) {
627 JComboBox source = (JComboBox)event.getSource();
628 Object object = source.getSelectedItem();
629 if(object instanceof Argument.ArgumentOption) {
630 Argument.ArgumentOption opt = (Argument.ArgumentOption)object;
631 if(opt != null) {
632 source.setToolTipText(opt.getToolTip());
633 }
634 else {
635 source.setToolTipText(StaticStrings.EMPTY_STR);
636 }
637 }
638 }
639 }
640}
Note: See TracBrowser for help on using the repository browser.