source: trunk/gli/src/org/greenstone/gatherer/cdm/ClassifierManager.java@ 12633

Last change on this file since 12633 was 12633, checked in by mdewsnip, 18 years ago

Kissed the horrible old plugins.dat and classifiers.dat files goodbye...

  • Property svn:keywords set to Author Date Id Revision
File size: 27.1 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.io.*;
32import java.net.*;
33import java.util.*;
34import java.util.jar.*;
35import javax.swing.*;
36import javax.swing.event.*;
37import org.apache.xerces.parsers.*;
38import org.greenstone.gatherer.Configuration;
39import org.greenstone.gatherer.DebugStream;
40import org.greenstone.gatherer.Dictionary;
41import org.greenstone.gatherer.Gatherer;
42import org.greenstone.gatherer.LocalGreenstone;
43import org.greenstone.gatherer.gui.DesignPaneHeader;
44import org.greenstone.gatherer.gui.GComboBox;
45import org.greenstone.gatherer.gui.GLIButton;
46import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
47import org.greenstone.gatherer.util.JarTools;
48import org.greenstone.gatherer.util.StaticStrings;
49import org.greenstone.gatherer.util.Utility;
50import org.greenstone.gatherer.util.XMLTools;
51import org.w3c.dom.*;
52import org.xml.sax.*;
53
54/** This class is responsible for keeping track of all the classifiers assigned to this collection, and providing methods for adding and removing them.
55 * @author John Thompson, Greenstone Digital Library, University of Waikato
56 * @version 2.3
57 */
58public class ClassifierManager
59 extends DOMProxyListModel
60{
61 // A list of all the classifiers in the core Greenstone "perllib/classify" folder (arguments may not be loaded)
62 private ArrayList core_greenstone_classifiers_list = null;
63
64 /** The controls for editing the contents of this manager. */
65 private Control controls = null;
66
67 private DOMProxyListModel model;
68
69 /** Constructor.
70 * @see org.greenstone.gatherer.cdm.DynamicListModel
71 * @see org.greenstone.gatherer.collection.CollectionManager
72 */
73 public ClassifierManager() {
74 super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.CLASSIFY_ELEMENT, new Classifier());
75 this.model = this;
76 DebugStream.println("ClassifierManager: " + getSize() + " classifiers parsed.");
77
78 core_greenstone_classifiers_list = loadClassifiersList();
79 }
80
81
82 // --------------------------------------------------------------------------------------------------------
83
84
85 /** Retrieve a list of the classifiers that are available to be added to the collection. */
86 private Object[] getAvailableClassifiers()
87 {
88 ArrayList available = new ArrayList();
89
90 // Add all the non-abstract core Greenstone classifiers
91 for (int i = 0; i < core_greenstone_classifiers_list.size(); i++) {
92 Classifier classifier = (Classifier) core_greenstone_classifiers_list.get(i);
93 if (!classifier.isAbstract()) {
94 available.add(classifier);
95 }
96 }
97
98 // Sort the available classifiers into alphabetical order
99 Collections.sort(available);
100
101 return available.toArray();
102 }
103
104
105 public Classifier getClassifier(String classifier_name, boolean arguments_required)
106 {
107 for (int i = 0; i < core_greenstone_classifiers_list.size(); i++) {
108 Classifier classifier = (Classifier) core_greenstone_classifiers_list.get(i);
109 if (classifier.getName().equals(classifier_name)) {
110 if (arguments_required) {
111 if (classifier.getArguments().size() == 0) {
112 loadClassifierInfo(classifier);
113 }
114 else {
115 System.err.println("Already loaded arguments for " + classifier_name + "!");
116 }
117 }
118 return classifier;
119 }
120 }
121
122 return null;
123 }
124
125
126 private void loadClassifierInfo(Classifier classifier)
127 {
128 System.err.println("Loading arguments for " + classifier.getName() + "...");
129
130 // Run classifierfo.pl to get the list of classifiers
131 try {
132 StringBuffer xml = null;
133 if (Gatherer.isGsdlRemote) {
134 // !! TO DO
135 }
136 else {
137 ArrayList args = new ArrayList();
138 if (Utility.isWindows()) {
139 args.add(Configuration.perl_path);
140 args.add("-S");
141 }
142 args.add(LocalGreenstone.getBinScriptDirectoryPath() + "classinfo.pl");
143 args.add("-xml");
144 args.add("-language");
145 args.add(Configuration.getLanguage());
146 args.add(classifier.getName());
147
148 // Run the classinfo.pl process
149 Runtime runtime = Runtime.getRuntime();
150 Process process = runtime.exec((String[]) args.toArray(new String[] { }));
151 InputStream input_stream = process.getErrorStream();
152 xml = XMLTools.readXMLStream(input_stream);
153 }
154
155 if (xml.length() > 0) {
156 parseClassifierInfoXML(classifier, xml.toString());
157 }
158 else {
159 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_XML_Parse_Failed", classifier.getName()), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
160 }
161 }
162 catch (Exception exception) {
163 DebugStream.printStackTrace(exception);
164 }
165 }
166
167
168 private ArrayList loadClassifiersList()
169 {
170 System.err.println("In loadClassifiersList()...");
171
172 // Run classifierfo.pl to get the list of classifiers
173 try {
174 StringBuffer xml = null;
175 if (Gatherer.isGsdlRemote) {
176 // !! TO DO
177 }
178 else {
179 ArrayList args = new ArrayList();
180 if (Utility.isWindows()) {
181 args.add(Configuration.perl_path);
182 args.add("-S");
183 }
184 args.add(LocalGreenstone.getBinScriptDirectoryPath() + "classinfo.pl");
185 args.add("-listall");
186 args.add("-xml");
187
188 // Run the classinfo.pl process
189 Runtime runtime = Runtime.getRuntime();
190 Process process = runtime.exec((String[]) args.toArray(new String[] { }));
191 InputStream input_stream = process.getErrorStream();
192 xml = XMLTools.readXMLStream(input_stream);
193 }
194
195 if (xml.length() > 0) {
196 return parseClassifiersListXML(xml.toString());
197 }
198 else {
199 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_List_XML_Parse_Failed"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
200 }
201 }
202 catch (Exception exception) {
203 DebugStream.printStackTrace(exception);
204 }
205
206 return null;
207 }
208
209
210 private void parseClassifierInfoXML(Classifier classifier, String xml)
211 {
212 Document document = XMLTools.parseXML(new StringReader(xml));
213 parseClassifierInfoXMLNode(classifier, document.getDocumentElement());
214 }
215
216
217 private void parseClassifierInfoXMLNode(Classifier classifier, Node root_node)
218 {
219 for (Node node = root_node.getFirstChild(); node != null; node = node.getNextSibling()) {
220 String node_name = node.getNodeName();
221
222 if (node_name.equalsIgnoreCase("Name")) {
223 classifier.setName(XMLTools.getValue(node));
224 }
225 else if (node_name.equals("Desc")) {
226 classifier.setDescription(XMLTools.getValue(node));
227 }
228 else if (node_name.equals("Abstract")) {
229 classifier.setIsAbstract(XMLTools.getValue(node).equalsIgnoreCase(CollectionConfiguration.YES_STR));
230 }
231 // Parse the classifier arguments
232 else if (node_name.equalsIgnoreCase("Arguments")) {
233 for (Node argument_node = node.getFirstChild(); argument_node != null; argument_node = argument_node.getNextSibling()) {
234 // An option
235 if (argument_node.getNodeName().equalsIgnoreCase("Option")) {
236 Argument argument = new Argument();
237 argument.parseXML((Element) argument_node);
238 classifier.addArgument(argument);
239 }
240 }
241 }
242 // A super classifier class
243 else if (node_name.equalsIgnoreCase("ClassInfo")) {
244 Classifier super_classifier = new Classifier();
245 parseClassifierInfoXMLNode(super_classifier, node);
246 classifier.setSuper(super_classifier);
247 }
248 }
249 }
250
251
252 private ArrayList parseClassifiersListXML(String xml)
253 {
254 ArrayList classifiers_list = new ArrayList();
255
256 Document document = XMLTools.parseXML(new StringReader(xml));
257 Node root = document.getDocumentElement();
258 for (Node node = root.getFirstChild(); node != null; node = node.getNextSibling()) {
259 String node_name = node.getNodeName();
260
261 if (node_name.equals("ClassInfo")) {
262 Classifier classifier = new Classifier();
263 parseClassifierInfoXMLNode(classifier, node);
264 classifiers_list.add(classifier);
265 }
266 }
267
268 return classifiers_list;
269 }
270
271
272 // --------------------------------------------------------------------------------------------------------
273
274
275 /** Method to assign a classifier.
276 * @param classifier The base <strong>Classifier</strong> to assign.
277 * @see org.greenstone.gatherer.cdm.DynamicListModel
278 */
279 private void assignClassifier(Classifier classifier) {
280 if(!contains(classifier)) {
281 Element element = classifier.getElement();
282 // Locate where we should insert this new classifier.
283 Node target_node = CollectionConfiguration.findInsertionPoint(element);
284 add(root, classifier, target_node);
285 Gatherer.c_man.configurationChanged();
286 }
287 }
288
289
290 /** Destructor. */
291 public void destroy()
292 {
293 if (controls != null) {
294 controls.destroy();
295 controls = null;
296 }
297 }
298
299
300 /** Method to retrieve the classifier with the given index.
301 * @param index The index of the desired classifier as an <i>int</i>.
302 * @return The requested Classifier or <i>null</i> if no such classifier exists.
303 */
304 public Classifier getClassifier(int index) {
305 if(0 <= index && index < getSize()) {
306 return (Classifier) getElementAt(index);
307 }
308 return null;
309 }
310
311 /** Method to retrieve the control for this manager.
312 * @return the Control for editing classifiers
313 */
314 public Control getControls() {
315 if(controls == null) {
316 // Build controls
317 this.controls = new ClassifierControl();
318 }
319 return controls;
320 }
321
322 /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden
323 * @param mode the new mode as an int
324 */
325 public void modeChanged(int mode) {
326
327 }
328
329
330
331 /** Determine if the Phind classifier has been assigned.
332 * @return true if it has, false otherwise
333 */
334 public boolean isPhindClassifierAssigned() {
335 for(int i = 0; i < getSize(); i++) {
336 Classifier classifier = (Classifier) getElementAt(i);
337 if(classifier.getName().equalsIgnoreCase(StaticStrings.PHIND_CLASSIFIER)) {
338 return true;
339 }
340 classifier = null;
341 }
342 return false;
343 }
344
345 /** Method to move a classifier in the list order.
346 * @param classifier the Classifier you want to move.
347 * @param direction true to move the classifier up, false to move it down.
348 * @param all true to move to move all the way, false for a single step.
349 */
350 private void moveClassifier(Classifier classifier, boolean direction, boolean all) {
351 if(getSize() < 2) {
352 DebugStream.println("Not enough classifiers to allow moving.");
353 return;
354 }
355 if(all) {
356 // Move to top
357 if(direction) {
358 // Remove the moving classifier
359 remove(classifier);
360 // Retrieve the first classifier
361 Classifier first_classifier = (Classifier) getElementAt(0);
362 // Add the moving classifier before the first classifier
363 addBefore(classifier, first_classifier);
364 first_classifier = null;
365 }
366 else {
367 // Remove the moving classifier
368 remove(classifier);
369 // And add after last classifier
370 add(getSize(), classifier);
371 }
372 }
373 else {
374 // Try to move the classifier one step in the desired direction.
375 int index = indexOf(classifier);
376 ///ystem.err.println("Index of " + classifier + " = " + index);
377 if(direction) {
378 index--;
379 if(index < 0) {
380 String args[] = new String[2];
381 args[0] = Dictionary.get("CDM.ClassifierManager.Classifier");
382 args[1] = classifier.getName();
383 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.Move.At_Top", args), Dictionary.get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE);
384 return;
385 }
386 remove(classifier);
387 add(index, classifier);
388 }
389 else {
390 index++;
391 if(index >= getSize()) {
392 String args[] = new String[2];
393 args[0] = Dictionary.get("CDM.ClassifierManager.Classifier_Str");
394 args[1] = classifier.getName();
395 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.Move.At_Bottom", args), Dictionary.get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE);
396 return;
397 }
398 remove(classifier);
399 add(index, classifier);
400 }
401 }
402
403 Gatherer.c_man.configurationChanged();
404 // tell the format manager to update the names of its format statements
405 Gatherer.c_man.getCollection().cdm.format_manager.refresh();
406 }
407
408 /** This method removes an assigned classifier. I was tempted to call it unassign, but remove is more consistant. Note that there is no way to remove a classifier from the library.
409 * @param classifier The Classifier to remove
410 * @see org.greenstone.gatherer.cdm.DynamicListModel
411 */
412 private void removeClassifier(Classifier classifier) {
413 remove(classifier);
414 Gatherer.c_man.configurationChanged();
415 }
416
417
418 /** A class which provides controls for assigned and editing classifiers. */
419 private class ClassifierControl
420 extends JPanel
421 implements Control {
422 /** A combobox containing all of the known classifiers, including those that may have already been assigned. */
423 private JComboBox classifier_combobox = null;
424 /** Button for adding classifiers. */
425 private JButton add = null;
426 /** Button for configuring the selected classifier. */
427 private JButton configure = null;
428 private JButton move_down_button;
429 private JButton move_up_button;
430
431 /** Button to remove the selected classifier. */
432 private JButton remove = null;
433
434 /** A list of assigned classifiers. */
435 private JList classifier_list = null;
436
437 /** Constructor.
438 * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.AddListener
439 * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.ConfigureListener
440 * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.RemoveListener
441 */
442 public ClassifierControl()
443 {
444 // Create
445 add = new GLIButton(Dictionary.get("CDM.ClassifierManager.Add"), Dictionary.get("CDM.ClassifierManager.Add_Tooltip"));
446
447 JPanel button_pane = new JPanel();
448 JPanel central_pane = new JPanel();
449
450configure = new GLIButton(Dictionary.get("CDM.ClassifierManager.Configure"), Dictionary.get("CDM.ClassifierManager.Configure_Tooltip"));
451 configure.setEnabled(false);
452
453 JPanel header_pane = new DesignPaneHeader("CDM.GUI.Classifiers", "classifiers");
454
455 ClassifierComboboxListener ccl = new ClassifierComboboxListener();
456 classifier_combobox = new JComboBox(getAvailableClassifiers());
457 classifier_combobox.setEditable(false);
458 if(classifier_combobox.getItemCount() > 0) {
459 classifier_combobox.setSelectedIndex(0);
460 ccl.itemStateChanged(new ItemEvent(classifier_combobox, 0, null, ItemEvent.SELECTED));
461 }
462
463 JLabel classifier_label = new JLabel(Dictionary.get("CDM.ClassifierManager.Classifier"));
464
465 classifier_list = new JList(model);
466 classifier_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
467 JLabel classifier_list_label = new JLabel(Dictionary.get("CDM.ClassifierManager.Assigned"));
468
469 classifier_list_label.setOpaque(true);
470
471 JPanel classifier_list_pane = new JPanel();
472 JPanel classifier_pane = new JPanel();
473 remove = new GLIButton(Dictionary.get("CDM.ClassifierManager.Remove"), Dictionary.get("CDM.ClassifierManager.Remove_Tooltip"));
474 remove.setEnabled(false);
475
476 JPanel temp = new JPanel(new BorderLayout());
477
478 JPanel move_button_pane = new JPanel();
479
480 move_up_button = new GLIButton(Dictionary.get("CDM.Move.Move_Up"), JarTools.getImage("arrow-up.gif"), Dictionary.get("CDM.Move.Move_Up_Tooltip"));
481 move_up_button.setEnabled(false);
482
483 move_down_button = new GLIButton(Dictionary.get("CDM.Move.Move_Down"), JarTools.getImage("arrow-down.gif"), Dictionary.get("CDM.Move.Move_Down_Tooltip"));
484 move_down_button.setEnabled(false);
485
486 // Listeners
487 add.addActionListener(new AddListener());
488 add.addActionListener(CollectionDesignManager.buildcol_change_listener);
489 classifier_combobox.addItemListener(ccl);
490 configure.addActionListener(new ConfigureListener());
491 configure.addActionListener(CollectionDesignManager.buildcol_change_listener);
492 remove.addActionListener(new RemoveListener());
493 remove.addActionListener(CollectionDesignManager.buildcol_change_listener);
494 classifier_list.addMouseListener(new ClickListener());
495 classifier_list.addListSelectionListener(new ListListener());
496 ccl = null;
497
498 MoveListener ml = new MoveListener();
499 move_down_button.addActionListener(ml);
500 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
501 move_up_button.addActionListener(ml);
502 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
503
504 // Layout
505 move_button_pane.setLayout(new GridLayout(4,1));
506 move_button_pane.add(move_up_button);
507 move_button_pane.add(new JPanel());
508 move_button_pane.add(new JPanel());
509 move_button_pane.add(move_down_button);
510
511 classifier_list_label.setBorder(BorderFactory.createEmptyBorder(0,2,0,2));
512
513 classifier_list_pane.setLayout(new BorderLayout());
514 classifier_list_pane.add(classifier_list_label, BorderLayout.NORTH);
515 classifier_list_pane.add(new JScrollPane(classifier_list), BorderLayout.CENTER);
516 classifier_list_pane.add(move_button_pane, BorderLayout.EAST);
517
518 classifier_label.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
519
520 classifier_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
521 classifier_pane.setLayout(new BorderLayout(5,0));
522 classifier_pane.add(classifier_label, BorderLayout.WEST);
523 classifier_pane.add(classifier_combobox, BorderLayout.CENTER);
524
525 button_pane.setLayout(new GridLayout(1, 3));
526 button_pane.add(add);
527 button_pane.add(configure);
528 button_pane.add(remove);
529
530 temp.add(classifier_pane, BorderLayout.NORTH);
531 temp.add(button_pane, BorderLayout.SOUTH);
532
533 central_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
534 central_pane.setLayout(new BorderLayout());
535 central_pane.add(classifier_list_pane, BorderLayout.CENTER);
536 central_pane.add(temp, BorderLayout.SOUTH);
537
538 setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
539 setLayout(new BorderLayout());
540 add(header_pane, BorderLayout.NORTH);
541 add(central_pane, BorderLayout.CENTER);
542 }
543
544 /** Method which acts like a destructor, tidying up references to persistant objects.
545 */
546 public void destroy() {
547 add = null;
548 classifier_combobox = null;
549 classifier_list = null;
550 configure = null;
551 //instructions = null;
552 remove = null;
553 }
554
555 public void gainFocus() {
556 }
557
558 public void loseFocus() {
559 }
560
561 /** This class listens for actions upon the add button in the controls, and if detected calls the assignClassifier() method.
562 */
563 private class AddListener
564 implements ActionListener {
565 /** Any implementation of ActionListener must include this method so that we can be informed when an action has occured on one of our target controls, so that we can add the selected Classifier.
566 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
567 * @see org.greenstone.gatherer.Gatherer
568 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration
569 * @see org.greenstone.gatherer.cdm.Classifier
570 */
571 public void actionPerformed(ActionEvent event) {
572 Object selected_object = classifier_combobox.getSelectedItem();
573 // If there is something in the combobox, but we haven't registered a selection, then add the object and select it!
574 if(selected_object != null) {
575 // Retrieve the base classifier
576 Classifier base_classifier = getClassifier(selected_object.toString(), true);
577
578 // Create a new element in the DOM
579 Element element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.CLASSIFY_ELEMENT);
580 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, base_classifier.getName());
581 Classifier new_classifier = new Classifier(element, base_classifier);
582
583 element = null;
584 // Automatically chain to configuration. This ensures required arguments are filled out.
585 ArgumentConfiguration ac = new ArgumentConfiguration(new_classifier);
586 if(ac.display()) {
587 if(!model.contains(new_classifier)) {
588 assignClassifier(new_classifier);
589 classifier_list.setSelectedValue(new_classifier, true);
590 }
591 else {
592 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
593 }
594 }
595 ac = null;
596 new_classifier = null;
597 }
598 }
599 }
600
601 /** This listener reacts to changes in the current selection of the classifier combobox. */
602 private class ClassifierComboboxListener
603 implements ItemListener {
604 /** When a user selects a certain classifier, update the tooltip to show the classifier description. */
605 public void itemStateChanged(ItemEvent event) {
606 if(event.getStateChange() == ItemEvent.SELECTED) {
607 // Retrieve the selected classifier
608 Classifier current_selection = (Classifier) classifier_combobox.getSelectedItem();
609 // And reset the tooltip.
610 classifier_combobox.setToolTipText(Utility.formatHTMLWidth(current_selection.getDescription(), 40));
611 current_selection = null;
612 }
613 }
614 }
615
616 /** Listens for double clicks apon the list and react as if the configure button was pushed. */
617 private class ClickListener
618 extends MouseAdapter {
619 /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt.
620 * @param event A <strong>MouseEvent</strong> containing information about the mouse click.
621 */
622 public void mouseClicked(MouseEvent event) {
623 if(event.getClickCount() == 2 ) {
624 if(!classifier_list.isSelectionEmpty()) {
625 Classifier classifier = (Classifier) classifier_list.getSelectedValue();
626 ArgumentConfiguration ac = new ArgumentConfiguration(classifier);
627 if(ac.display()) {
628 refresh(classifier);
629 }
630 ac.destroy();
631 ac = null;
632 // cos I can't be bothered checking every argument to see if it has changed or not, we'll asasume that the configuration has changed if someone has clicked configure
633 Gatherer.c_man.configurationChanged();
634 }
635 }
636 }
637 }
638
639 /** This class listens for actions upon the configure button in the controls, and if detected creates a new ArgumentConfiguration dialog box to allow for configuration.
640 */
641 private class ConfigureListener
642 implements ActionListener {
643 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls.
644 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
645 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration
646 * @see org.greenstone.gatherer.cdm.Classifier
647 */
648 public void actionPerformed(ActionEvent event) {
649 if(!classifier_list.isSelectionEmpty()) {
650 Classifier classifier = (Classifier) classifier_list.getSelectedValue();
651 ArgumentConfiguration ac = new ArgumentConfiguration(classifier);
652 if(ac.display()) {
653 refresh(classifier);
654 }
655 ac.destroy();
656 ac = null;
657 // cos I can't be bothered checking every argument to see if it has changed or not, we'll asasume that the configuration has changed if someone has clicked configure
658 Gatherer.c_man.configurationChanged();
659 }
660 }
661 }
662
663 /** listens for changes in the list selection and enables the configure and remove buttons if there is a selection, disables them if there is no selection */
664 private class ListListener
665 implements ListSelectionListener {
666
667 public void valueChanged(ListSelectionEvent e) {
668 if (!e.getValueIsAdjusting()) { // we get two events for one change in list selection - use the false one ( the second one)
669 if (classifier_list.isSelectionEmpty()) {
670 move_up_button.setEnabled(false);
671 move_down_button.setEnabled(false);
672 configure.setEnabled(false);
673 remove.setEnabled(false);
674 }
675 else {
676 configure.setEnabled(true);
677 remove.setEnabled(true);
678 int selected_index = classifier_list.getSelectedIndex();
679 move_up_button.setEnabled(selected_index !=0);
680 move_down_button.setEnabled(selected_index != model.getSize()-1);
681 }
682 }
683 }
684 }
685
686 /** Listens for actions apon the move buttons in the manager controls, and if detected calls the <i>moveClassifier()</i> method of the manager with the appropriate details. */
687 private class MoveListener
688 implements ActionListener {
689 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls.
690 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
691 */
692 public void actionPerformed(ActionEvent event) {
693 if(!classifier_list.isSelectionEmpty()) {
694 Object object = classifier_list.getSelectedValue();
695 if(object instanceof Classifier) {
696 Classifier classifier = (Classifier) object;
697 if(event.getSource() == move_up_button) {
698 moveClassifier(classifier, true, false);
699 }
700 else if(event.getSource() == move_down_button) {
701 moveClassifier(classifier, false, false);
702 }
703 classifier_list.setSelectedValue(classifier, true);
704 }
705 }
706 }
707 }
708
709 /** This class listens for actions upon the remove button in the controls, and if detected calls the <i>removeClassifier()</i> method.
710 */
711 private class RemoveListener
712 implements ActionListener {
713 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls.
714 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
715 */
716 public void actionPerformed(ActionEvent event) {
717 if(classifier_list.isSelectionEmpty()) {
718 remove.setEnabled(false);
719 return;
720 }
721 int selected_index = classifier_list.getSelectedIndex();
722 Object selected_classifier = classifier_list.getSelectedValue();
723 if (!(selected_classifier instanceof Classifier)) {
724 return; // what else could we have here???
725 }
726 removeClassifier((Classifier)selected_classifier);
727
728 if (selected_index >= classifier_list.getModel().getSize()) {
729 selected_index--;
730 }
731 if (selected_index >=0) {
732 classifier_list.setSelectedIndex(selected_index);
733 } else {
734 // no more classifiers in the list
735 remove.setEnabled(false);
736 }
737 }
738 }
739 }
740}
Note: See TracBrowser for help on using the repository browser.