- Timestamp:
- 2003-07-15T13:55:22+12:00 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/cdm/ClassifierManager.java
r4838 r4932 6 6 * University of Waikato, New Zealand. 7 7 * 8 * <BR><BR>9 *10 8 * Author: John Thompson, Greenstone Digital Library, University of Waikato 11 9 * 12 * <BR><BR>13 *14 10 * Copyright (C) 1999 New Zealand Digital Library Project 15 *16 * <BR><BR>17 11 * 18 12 * This program is free software; you can redistribute it and/or modify … … 21 15 * (at your option) any later version. 22 16 * 23 * <BR><BR>24 *25 17 * This program is distributed in the hope that it will be useful, 26 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 27 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 20 * GNU General Public License for more details. 29 *30 * <BR><BR>31 21 * 32 22 * You should have received a copy of the GNU General Public License … … 36 26 */ 37 27 package org.greenstone.gatherer.cdm; 38 39 import java.awt.BorderLayout; 40 import java.awt.Color; 41 import java.awt.Component; 42 import java.awt.Dimension; 43 import java.awt.GridLayout; 44 import java.awt.event.ActionEvent; 45 import java.awt.event.ActionListener; 46 import java.awt.event.MouseAdapter; 47 import java.awt.event.MouseEvent; 48 import java.io.BufferedReader; 49 import java.io.File; 50 import java.io.FileInputStream; 51 import java.io.FileOutputStream; 52 import java.io.InputStream; 53 import java.io.InputStreamReader; 54 import java.io.ObjectInputStream; 55 import java.io.ObjectOutputStream; 56 import java.io.StringReader; 57 import java.lang.Exception; 58 import java.util.ArrayList; 59 import java.util.Collections; 60 import java.util.Enumeration; 61 import java.util.jar.JarFile; 62 import javax.swing.BorderFactory; 63 import javax.swing.DefaultListCellRenderer; 64 import javax.swing.JButton; 65 import javax.swing.JComboBox; 66 import javax.swing.JLabel; 67 import javax.swing.JList; 68 import javax.swing.JOptionPane; 69 import javax.swing.JPanel; 70 import javax.swing.JScrollPane; 71 import javax.swing.JTextArea; 72 import javax.swing.ListSelectionModel; 73 import javax.swing.event.ListSelectionEvent; 74 import javax.swing.event.ListSelectionListener; 75 import org.apache.xerces.parsers.DOMParser; 28 /************************************************************************************** 29 * Written: 01/05/02 30 * Revised: 16/08/02 Optimized and Commented. 31 * 11/07/03 DOM support 32 **************************************************************************************/ 33 import java.awt.*; 34 import java.awt.event.*; 35 import java.io.*; 36 import java.util.*; 37 import java.util.jar.*; 38 import javax.swing.*; 39 import javax.swing.event.*; 40 import org.apache.xerces.parsers.*; 76 41 import org.greenstone.gatherer.Gatherer; 77 42 import org.greenstone.gatherer.cdm.Argument; 43 import org.greenstone.gatherer.cdm.CollectionConfiguration; 78 44 import org.greenstone.gatherer.cdm.CollectionDesignManager; 79 45 import org.greenstone.gatherer.cdm.CommandTokenizer; 46 import org.greenstone.gatherer.cdm.Control; 80 47 import org.greenstone.gatherer.cdm.Classifier; 81 48 import org.greenstone.gatherer.cdm.CustomClassifier; 82 import org.greenstone.gatherer.cdm.D ynamicListModel;49 import org.greenstone.gatherer.cdm.DOMProxyListModel; 83 50 import org.greenstone.gatherer.file.FileNode; 84 import org.greenstone.gatherer. msm.ElementWrapper;51 import org.greenstone.gatherer.gui.GComboBox; 85 52 import org.greenstone.gatherer.msm.MSMEvent; 86 53 import org.greenstone.gatherer.msm.MSMListener; 87 54 import org.greenstone.gatherer.msm.MSMUtils; 88 55 import org.greenstone.gatherer.util.Utility; 89 import org.w3c.dom.Document; 90 import org.w3c.dom.Node; 91 import org.xml.sax.InputSource; 56 import org.w3c.dom.*; 57 import org.xml.sax.*; 92 58 /** This class is responsible for keeping track of all the classifiers assigned to this collection, and providing methods for adding and removing them. 93 59 * @author John Thompson, Greenstone Digital Library, University of Waikato 94 60 * @version 2.3 95 61 */ 96 // ####################################################################################97 // Optimization Saving98 // ####################################################################################99 // Vector -> ArrayList + Memory, + Processor, (pos. - Processor)100 // Unnecessary global references + Memory (5Kb+)101 // ####################################################################################102 62 public class ClassifierManager 103 implements MSMListener { 104 /** An interface to the Gatherer, the creator of this cdm module, for access to the Greenstone installation directory. */ 105 private Gatherer gatherer = null; 106 /** A reference to the CollectionDesignManager for access to other configuration managers. */ 107 private CollectionDesignManager manager = null; 63 extends DOMProxyListModel { 64 65 /** The default size for a label. */ 66 static final private Dimension LABEL_SIZE = new Dimension(140, 20); 67 68 /** A list of known, but currently unassigned, classifiers. */ 69 private ArrayList library = null; 108 70 /** The controls for editing the contents of this manager. */ 109 71 private Control controls = null; 110 /** A list of assigned classifiers. */ 111 private DynamicListModel assigned = null; 112 /** A list of known, but currently unassigned, classifiers. */ 113 private DynamicListModel reserve = null; 114 /** We may have somehow recieved a classifier command that are, in fact, custom classifiers which can refer to classifiers that haven't been parsed yet, so this holds a list of failed commands which are retried after the loading is complete. */ 115 private ArrayList unresolved_commands = null; 72 73 private DOMProxyListModel model; 74 116 75 /** Constructor. 117 * @param gatherer A reference to the <strong>Gatherer</strong> for access to the Dictionary.118 * @param manager A reference to the <strong>CollectionDesignManager</strong> itself.119 * @see org.greenstone.gatherer.Gatherer120 76 * @see org.greenstone.gatherer.cdm.DynamicListModel 121 77 * @see org.greenstone.gatherer.collection.CollectionManager … … 123 79 * @see org.greenstone.gatherer.msm.MSMListener 124 80 */ 125 public ClassifierManager( Gatherer gatherer, CollectionDesignManager manager) {126 this.assigned = new DynamicListModel();127 this. gatherer = gatherer;128 this.manager = manager;129 this.unresolved_commands = new ArrayList();81 public ClassifierManager() { 82 super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.CLASSIFY_ELEMENT, new Classifier()); 83 this.model = this; 84 Gatherer.println("ClassifierManager: " + getSize() + " classifiers parsed."); 85 // Reload/Create the library 130 86 loadClassifiers(); 131 87 saveClassifiers(); 132 // Register as a MSMListener. 133 Gatherer.c_man.getCollection().msm.addMSMListener(this); 134 } 135 /** Method to add a new classifier to reserve. 136 * @param classifier The new <strong>Classifier</strong>. 88 } 89 90 /** Method to add a new classifier to library. 91 * @param classifier The new <strong>Classifier</strong>. 92 * @see org.greenstone.gatherer.cdm.DynamicListModel 93 */ 94 public void addClassifier(Classifier classifier) { 95 if(!library.contains(classifier)) { 96 library.add(classifier); 97 } 98 } 99 100 /** Method to assign a classifier. 101 * @param classifier The base <strong>Classifier</strong> to assign. 102 * @see org.greenstone.gatherer.cdm.DynamicListModel 103 */ 104 public void assignClassifier(Classifier classifier) { 105 if(!contains(classifier)) { 106 Element element = classifier.getElement(); 107 // Locate where we should insert this new classifier. 108 Node target_node = CollectionConfiguration.findInsertionPoint(element); 109 add(root, classifier, target_node); 110 Gatherer.c_man.configurationChanged(); 111 } 112 } 113 114 /** Destructor. 115 * @see org.greenstone.gatherer.Gatherer 116 * @see org.greenstone.gatherer.cdm.CollectionDesignManager 117 * @see org.greenstone.gatherer.cdm.DynamicListModel 118 */ 119 public void destroy() { 120 if(controls != null) { 121 controls.destroy(); 122 controls = null; 123 } 124 library.clear(); 125 library = null; 126 } 127 128 public Classifier getBaseClassifier(String name) { 129 int library_size = library.size(); 130 for(int i = 0; i < library_size; i++) { 131 Classifier classifier = (Classifier) library.get(i); 132 if(classifier.getName().equals(name)) { 133 return classifier; 134 } 135 } 136 // No success. 137 return null; 138 } 139 140 /** Method to retrieve the classifier with the given index. 141 * @param index The index of the desired classifier as an <i>int</i>. 142 * @return The requested Classifier or <i>null</i> if no such classifier exists. 143 */ 144 public Classifier getClassifier(int index) { 145 if(0 <= index && index < getSize()) { 146 return (Classifier) getElementAt(index); 147 } 148 return null; 149 } 150 151 /** Method to retrieve the control for this manager. 152 * @return the Control for editing classifiers 153 */ 154 public Control getControls() { 155 if(controls == null) { 156 // Build controls 157 this.controls = new ClassifierControl(); 158 } 159 return controls; 160 } 161 162 /** Method to move a classifier in the list order. 163 * @param classifier the Classifier you want to move. 164 * @param direction true to move the classifier up, false to move it down. 165 * @param all true to move to move all the way, false for a single step. 166 */ 167 public void moveClassifier(Classifier classifier, boolean direction, boolean all) { 168 if(getSize() < 2) { 169 Gatherer.println("Not enough classifiers to allow moving."); 170 return; 171 } 172 if(all) { 173 // Move to top 174 if(direction) { 175 // Remove the moving classifier 176 remove(classifier); 177 // Retrieve the first classifier 178 Classifier first_classifier = (Classifier) getElementAt(0); 179 // Add the moving classifier before the first classifier 180 addBefore(classifier, first_classifier); 181 first_classifier = null; 182 Gatherer.c_man.configurationChanged(); 183 } 184 else { 185 // Remove the moving classifier 186 remove(classifier); 187 // And add after last classifier 188 add(getSize(), classifier); 189 } 190 } 191 else { 192 // Try to move the classifier one step in the desired direction. 193 int index = indexOf(classifier); 194 ///ystem.err.println("Index of " + classifier + " = " + index); 195 if(direction) { 196 index--; 197 if(index < 0) { 198 String args[] = new String[2]; 199 args[0] = get("CDM.ClassifierManager.Classifier"); 200 args[1] = classifier.getName(); 201 JOptionPane.showMessageDialog(Gatherer.g_man, get("CDM.Move.At_Top", args), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 202 return; 203 } 204 remove(classifier); 205 add(index, classifier); 206 Gatherer.c_man.configurationChanged(); 207 } 208 else { 209 index++; 210 if(index >= getSize()) { 211 String args[] = new String[2]; 212 args[0] = get("CDM.ClassifierManager.Classifier_Str"); 213 args[1] = classifier.getName(); 214 JOptionPane.showMessageDialog(Gatherer.g_man, get("CDM.Move.At_Bottom", args), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 215 return; 216 } 217 remove(classifier); 218 add(index, classifier); 219 Gatherer.c_man.configurationChanged(); 220 } 221 } 222 } 223 224 /** 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. 225 * @param classifier The Classifier to remove 137 226 * @see org.greenstone.gatherer.cdm.DynamicListModel 138 227 */ 139 public void addClassifier(Classifier classifier) { 140 if(!reserve.contains(classifier)) { 141 reserve.addElement(classifier); 142 } 143 } 144 /** Method to assign a classifier. 145 * @param classifier The reserve <strong>Classifier</strong> to assign. 146 * @see org.greenstone.gatherer.cdm.DynamicListModel 228 public void removeClassifier(Classifier classifier) { 229 remove(classifier); 230 Gatherer.c_man.configurationChanged(); 231 } 232 233 /** Method to cache the current contents of library (known classifiers) to file. 234 * @see org.greenstone.gatherer.util.Utility 235 */ 236 public void saveClassifiers() { 237 try { 238 FileOutputStream file = new FileOutputStream(Utility.BASE_DIR + "classifiers.dat"); 239 ObjectOutputStream out = new ObjectOutputStream(file); 240 out.writeObject(library); 241 out.close(); 242 } 243 catch (Exception error) { 244 } 245 } 246 247 /** Retrieve a phrase from the dictionary based on a certain key. 248 * @param key The search <strong>String</strong>. 249 * @return The matching phrase from the Dictionary. 147 250 */ 148 public void assignClassifier(Classifier classifier) { 149 if(!assigned.contains(classifier)) { 150 assigned.addElement(classifier); 151 classifier.setManager(this); 152 gatherer.c_man.configurationChanged(); 153 } 154 } 155 /** Method to assign a classifier. 156 * @param classifier The <strong>CustomClassifier</strong> to assign. 157 * @see org.greenstone.gatherer.cdm.DynamicListModel 251 private String get(String key) { 252 return get(key, (String[])null); 253 } 254 /** Retrieve a phrase from the dictionary based on a certain key and certain arguments. 255 * @param key The search <strong>String</strong>. 256 * @param args A <strong>String[]</strong> used to complete and format the returned phrase. 257 * @return The matching phrase from the Dictionary. 258 * @see org.greenstone.gatherer.Dictionary 259 * @see org.greenstone.gatherer.Gatherer 158 260 */ 159 public void assignClassifier(CustomClassifier classifier) { 160 if(!assigned.contains(classifier)) { 161 assigned.addElement(classifier); 162 classifier.setManager(this); 163 gatherer.c_man.configurationChanged(); 164 } 165 } 166 /** Destructor. 167 * @see org.greenstone.gatherer.Gatherer 168 * @see org.greenstone.gatherer.cdm.CollectionDesignManager 169 * @see org.greenstone.gatherer.cdm.DynamicListModel 170 */ 171 public void destroy() { 172 // Deregister as a listener 173 if(gatherer.c_man != null && gatherer.c_man.msm != null) { 174 gatherer.c_man.msm.removeMSMListener(this); 175 } 176 // Null globals 177 assigned = null; 178 controls = null; 179 gatherer = null; 180 manager = null; 181 reserve = null; 182 unresolved_commands = null; 183 } 184 /** Method to retrieve the classifier with the given index. 185 * @param index The index of the desired classifier as an <i>int</i>. 186 * @return The requested Classifier as an <strong>Object</strong> or <i>null</i> if no such classifier exists. 187 * @see org.greenstone.gatherer.cdm.DynamicListModel 188 */ 189 public Object getClassifier(int index) { 190 if(0 <= index && index < assigned.size()) { 191 return assigned.get(index); 192 } 193 return null; 194 } 195 /** Method to retrieve the named classifier. 196 * @param name The name of the desired classifier as a <strong>String</strong>. 197 * @return The requested <strong>Classifier</strong> or <i>null</i> if no such classifier exists. 198 * @see org.greenstone.gatherer.cdm.DynamicListModel 199 */ 200 public Classifier getClassifier(String name) { 201 for(int i = 0; i < reserve.size(); i++) { 202 Classifier classifier = (Classifier)reserve.get(i); 203 if(classifier.getName().equals(name)) { 204 return classifier; 205 } 206 } 207 // No success. 208 return null; 209 } 210 /** Method to retrieve the control for this manager. 211 * @return A <strong>JPanel</strong> containing the controls. 212 */ 213 public JPanel getControls() { 214 if(controls == null) { 215 controls = new Control(); 216 } 217 return controls; 218 } 219 /** Called whenever a metadata element changes significantly. 220 * @param event A <strong>MSMEvent</strong> choc' full of event informationy goodness. 221 */ 222 public void elementChanged(MSMEvent event) { 223 // Don't really care, as the elements dealt with here are all live references so changes like identifier change will propagate immediately. 224 } 225 /** Method to find the index of the given classifier within the assigned classifiers. 226 * @param classifier The <strong>Classifier</strong> whose index you wish to find. 227 * @return The index of the classifier as an <i>int</i>, which has a value of -1 if the classifier was not found. 228 * @see org.greenstone.gatherer.cdm.DynamicListModel 229 */ 230 public int indexOf(Classifier classifier) { 231 for(int i = 0; i < assigned.size(); i++) { 232 Object elem = assigned.get(i); 233 if (elem instanceof Classifier) { 234 Classifier sibling = (Classifier)elem; 235 if(sibling.equals(classifier)) { 236 return i; 237 } 238 } 239 } 240 return -1; 241 } 242 // these two methods assume that a custome classifier can never be the same as a classifier 243 public int indexOf(CustomClassifier classifier) { 244 for(int i = 0; i < assigned.size(); i++) { 245 Object elem = assigned.get(i); 246 if (elem instanceof CustomClassifier) { 247 CustomClassifier sibling = (CustomClassifier) assigned.get(i); 248 if(sibling.equals(classifier)) { 249 return i; 250 } 251 } 252 } 253 return -1; 254 } 255 /** Method to invalidate controls after a significant change in the system state. 256 */ 257 public void invalidateControls() { 258 if(controls != null) { 259 controls.destroy(); 260 } 261 controls = null; 262 } 261 private String get(String key, String arg) { 262 String[] args = null; 263 if(arg != null) { 264 args = new String[1]; 265 args[0] = arg; 266 } 267 return get(key, args); 268 } 269 270 private String get(String key, String[] args) { 271 if(key.indexOf(".") == -1) { 272 key = "CDM.ClassifierManager." + key; 273 } 274 return Gatherer.dictionary.get(key, args); 275 } 276 277 /** Method to extract just the classifiers name from a file object. 278 * @param classifier The <strong>File</strong> which references a certain classifier. 279 * @return A <strong>String</strong> containing just the classifiers name, without extension. 280 */ 281 private String getClassifierName(File classifier) { 282 String name = classifier.getName(); 283 if(name.indexOf(".") != -1) { 284 name = name.substring(0, name.indexOf(".")); 285 } 286 return name; 287 } 288 263 289 /** Method to load the details of a single plug-in. 264 265 266 p ublicvoid loadClassifier(File classifier) {290 * @param classifier The classifier <strong>File</strong> you wish to load. 291 */ 292 private void loadClassifier(File classifier) { 267 293 ///ystem.err.println("Attempting to parse " + classifier.toString()); 268 294 Document document = null; … … 274 300 if(Utility.isWindows()) { 275 301 args = new String[4]; 276 if( gatherer.config.perl_path != null) {277 args[0] = gatherer.config.perl_path;302 if(Gatherer.config.perl_path != null) { 303 args[0] = Gatherer.config.perl_path; 278 304 } 279 305 else { 280 306 args[0] = "Perl.exe"; 281 307 } 282 args[1] = gatherer.config.gsdl_path + "bin" + File.separator + "script" + File.separator + "classinfo.pl";308 args[1] = Gatherer.config.gsdl_path + "bin" + File.separator + "script" + File.separator + "classinfo.pl"; 283 309 args[2] = "-xml"; 284 310 args[3] = getClassifierName(classifier); … … 334 360 } 335 361 if(document != null) { 336 parse(document.getDocumentElement()); 337 } 338 } 339 /** Called whenever the metadata value associated to a certain record changes. */ 340 public void metadataChanged(MSMEvent event) { 341 FileNode record = event.getRecord(); 342 if(record != null) { 343 for(int i = 0; i < assigned.size(); i++) { 344 Object object = assigned.get(i); 345 if(object instanceof CustomClassifier) { 346 CustomClassifier classifier = (CustomClassifier) object; 347 if(!classifier.isProcessing()) { // are we already in the middle of processing?? 348 classifier.process(record); 349 } 350 } 351 } 352 } 353 } 354 /** This method attempts to parse a classifier command from a command string taken from the collection configuration file. This process is quite complex as not only must the correct classifier be matched but also all of the parameters given must be legal. If such a command is found, the classifier is immediately assigned. 355 * @param command The command <strong>String</strong> that may include classifier information. 356 * @return <i>true</i> if a classifier command was parsed, <i>false</i> otherwise. 357 * @see org.greenstone.gatherer.cdm.Argument 358 * @see org.greenstone.gatherer.cdm.Classifier 359 * @see org.greenstone.gatherer.cdm.CommandTokenizer 360 */ 361 public boolean parse(String command) { 362 String command_lc = command.toLowerCase(); 363 if(command_lc.startsWith("classify")) { 364 CommandTokenizer tokenizer = new CommandTokenizer(command); 365 if(tokenizer.countTokens() >= 2) { 366 tokenizer.nextToken(); // Throw away 'classifier' 367 String name = tokenizer.nextToken(); 368 // Try to locate the classifier with this name. 369 Classifier classifier = getClassifier(name); 370 // And if successful start to parse the arguments. 371 if(classifier != null) { 372 // Take a copy. 373 classifier = classifier.copy(); 374 String key = null; 375 while((key = tokenizer.nextToken()) != null) { 376 // Try to retrieve a matching argument. 377 Argument argument = classifier.getArgument(key); 378 if(argument != null) { 379 // Set as assigned. 380 argument.setAssigned(true); 381 // And if the argument is of a parameter type, parse a parameter. 382 if(argument.getType() != Argument.FLAG && tokenizer.hasMoreTokens()) { 383 String value = tokenizer.nextToken(); 384 ElementWrapper element = null; 385 // special check for metadata 386 if (argument.getType() == Argument.METADATA) { 387 value = value.replace(':', MSMUtils.NS_SEP); 388 if (value.indexOf(MSMUtils.NS_SEP)==-1){ 389 value = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + value; 390 } 391 // Now retrieve the element this refers to, if available. 392 element = Gatherer.c_man.getCollection().msm.getElement(value); 393 } 394 if(element != null) { 395 argument.setElementValue(element); 396 element = null; 397 } 398 else { 399 argument.setValue(value); 400 } 401 } 402 } 403 // Argument cannot be matched. 404 else { 405 String cur_key = key; 406 String value = tokenizer.nextToken(); 407 if(value.startsWith("-")) { 408 key = value; 409 value = null; 410 } 411 else { 412 key = null; 413 } 414 String custom = classifier.getCustom(); 415 if(custom == null) { 416 if(value == null) { 417 classifier.setCustom(cur_key); 418 } 419 else { 420 classifier.setCustom(cur_key + " " + value); 421 } 422 } 423 else { 424 if(value == null) { 425 classifier.setCustom(custom + " " + cur_key); 426 } 427 else { 428 classifier.setCustom(custom + " " + cur_key + " " + value); 429 } 430 } 431 } 432 } 433 assignClassifier(classifier); 434 return true; 435 } 436 else { 437 ///ystem.err.println("Unknown classifier"); 438 } 439 } 440 } 441 else if(command_lc.startsWith("customclassifier")) { 442 unresolved_commands.add(command); 443 return true; 444 } 445 return false; 446 } 447 /** 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 reserve. 448 * @param classifier The Classifier or CustomClassifier, as an <strong>Object</strong>, to remove. 449 * @see org.greenstone.gatherer.cdm.DynamicListModel 450 */ 451 public void removeClassifier(Object classifier) { 452 assigned.removeElement(classifier); 453 gatherer.c_man.configurationChanged(); 454 } 455 /** Method which attempts to reparse obvious classifier commands which previously referenced unresovable Classifiers. 456 * @see org.greenstone.gatherer.cdm.Classifier 457 * @see org.greenstone.gatherer.cdm.CommandTokenizer 458 * @see org.greenstone.gatherer.cdm.CustomClassifier 459 */ 460 public void reparseUnresolved() { 461 for(int i = 0; i < unresolved_commands.size(); i++) { 462 String command = (String) unresolved_commands.get(i); 463 CommandTokenizer tokenizer = new CommandTokenizer(command); 464 if(tokenizer.countTokens() >= 6) { 465 tokenizer.nextToken();// Lose customclassifier 466 // Get class name. 467 String class_name = tokenizer.nextToken(); 468 // Parse arguments. 469 String replaces = null; 470 String separations = null; 471 while(tokenizer.hasMoreTokens()) { 472 String arg_name = tokenizer.nextToken(); 473 if(arg_name.equalsIgnoreCase("-replaces")) { 474 replaces = tokenizer.nextToken(); 475 } 476 else if (arg_name.equalsIgnoreCase("-separations")){ 477 separations = tokenizer.nextToken(); 478 } 479 } 480 try { 481 replaces = replaces.substring(2); 482 int index = Integer.parseInt(replaces); 483 Classifier original = (Classifier)getClassifier(index); 484 if(original != null) { 485 Class custom_classifier_class = Class.forName("org.greenstone.gatherer.cdm.custom." + class_name); 486 CustomClassifier custom_classifier = (CustomClassifier) custom_classifier_class.newInstance(); 487 custom_classifier.setGatherer(gatherer); 488 custom_classifier.recreate(original, separations); 489 assigned.add(index, custom_classifier); 490 assigned.removeElement(original); 491 } 492 else { 493 ///ystem.err.println("Missing original."); 494 } 495 } 496 catch (Exception error) { 497 error.printStackTrace(); 498 } 499 } 500 } 501 // Regardless of if they work, clear the commands. 502 unresolved_commands.clear(); 503 } 504 /** Method to cache the current contents of reserve (known classifiers) to file. 505 * @see org.greenstone.gatherer.util.Utility 506 */ 507 public void saveClassifiers() { 508 try { 509 FileOutputStream file = new FileOutputStream(Utility.BASE_DIR + "classifiers.dat"); 510 ObjectOutputStream out = new ObjectOutputStream(file); 511 out.writeObject(reserve); 512 out.close(); 513 } 514 catch (Exception error) { 515 } 516 } 517 /** Called when a metadata set changed significantly. 518 * @param event A <strong>MSMEvent</strong> containing information about the set change. 519 */ 520 public void setChanged(MSMEvent event) { 521 // Again, we would only worry about this if we contained 'inanimate' references to elements or something, but our references are live, and controls are rebuilt everytime a pop-up is needed. 522 } 523 /** Method used to determine the number of classifiers that have been assigned. 524 * @return An <i>int</i> which is the number of classifiers. 525 */ 526 public int size() { 527 return assigned.size(); 528 } 529 /** Method to print out a block of classifier commands, much like you'd find in a collection configuration file. 530 * @return A <strong>String</strong> containing a series of classifier commands separated by new lines. 531 * @see org.greenstone.gatherer.cdm.Classifier 532 * @see org.greenstone.gatherer.cdm.CustomClassifier 533 */ 534 public String toString() { 535 StringBuffer text = new StringBuffer(); 536 for(int i = 0; i < assigned.size(); i++) { 537 Object object = assigned.get(i); 538 if(object instanceof Classifier) { 539 Classifier classifier = (Classifier) object; 540 text.append(classifier.toStringConfig()); 541 } 542 else if(object instanceof CustomClassifier) { 543 CustomClassifier classifier = (CustomClassifier) object; 544 text.append(classifier.getCommand()); 545 text.append("\n"); 546 text.append(classifier.getCustomCommand(i)); 547 } 548 text.append("\n"); 549 } 550 text.append("\n"); 551 return text.toString(); 552 } 553 /** Called when a significant change has occured to a value tree for a certain element, however we take no further action. 554 * @param event A <strong>MSMEvent</strong> containing information relevant to the event. 555 */ 556 public void valueChanged(MSMEvent event) { 557 } 558 /** Retrieve a phrase from the dictionary based on a certain key. 559 * @param key The search <strong>String</strong>. 560 * @return The matching phrase from the Dictionary. 561 */ 562 private String get(String key) { 563 return get(key, null); 564 } 565 /** Retrieve a phrase from the dictionary based on a certain key and certain arguments. 566 * @param key The search <strong>String</strong>. 567 * @param args A <strong>String[]</strong> used to complete and format the returned phrase. 568 * @return The matching phrase from the Dictionary. 569 * @see org.greenstone.gatherer.Dictionary 570 * @see org.greenstone.gatherer.Gatherer 571 */ 572 private String get(String key, String arg) { 573 String[] args = null; 574 if(arg != null) { 575 args = new String[1]; 576 args[0] = arg; 577 } 578 if(key.indexOf(".") == -1) { 579 key = "CDM.ClassifierManager." + key; 580 } 581 return gatherer.dictionary.get(key, args); 582 } 583 /** Method to extract just the classifiers name from a file object. 584 * @param classifier The <strong>File</strong> which references a certain classifier. 585 * @return A <strong>String</strong> containing just the classifiers name, without extension. 586 */ 587 private String getClassifierName(File classifier) { 588 String name = classifier.getName(); 589 if(name.indexOf(".") != -1) { 590 name = name.substring(0, name.indexOf(".")); 591 } 592 return name; 593 } 362 parseXML(document.getDocumentElement()); 363 } 364 } 365 594 366 /** Method to initially load information from the standard plug-ins within the gsdl Perl library. 595 * @see org.greenstone.gatherer.cdm.DynamicListModel 596 * @see org.greenstone.gatherer.util.Utility 597 */ 367 * @see org.greenstone.gatherer.util.Utility 368 */ 598 369 private void loadClassifiers() { 599 370 // Attempt to restore the cached file. … … 601 372 FileInputStream file = new FileInputStream(Utility.BASE_DIR + "classifiers.dat"); 602 373 ObjectInputStream input = new ObjectInputStream(file); 603 reserve = (DynamicListModel) input.readObject();374 library = (ArrayList) input.readObject(); 604 375 } 605 376 catch (Exception error) { 606 377 } 607 if( reserve== null) {608 reserve = new DynamicListModel();609 610 String directory = gatherer.config.gsdl_path;378 if(library == null) { 379 library = new ArrayList(); 380 // Retrieve the gsdl home directory... 381 String directory = Gatherer.config.gsdl_path; 611 382 directory = directory + "perllib" + File.separator + "classify" + File.separator; 612 loadClassifiers(new File(directory)); 613 } 614 } 615 /** Method to load plug-in information from a specified directory. Of course no plug-ins may be found at this location. 616 * @param directory A <strong>File</strong> indicating the directory to be scanned for plug-ins. 617 * @see org.greenstone.gatherer.cdm.ParsingProgress 618 */ 619 private void loadClassifiers(File directory) { 620 File files[] = directory.listFiles(); 621 if(files != null) { 622 // Create a progress indicator. 623 ParsingProgress progress = new ParsingProgress(get("CDM.ClassifierManager.Parsing.Title"), get("CDM.ClassifierManager.Parsing.Message"), files.length); 624 for(int i = 0; i < files.length; i++) { 625 // We only want to check Perl Modules. 626 if(files[i].getName().endsWith(".pm")) { 627 loadClassifier(files[i]); 628 } 629 progress.inc(); 630 } 631 progress.dispose(); 632 progress.destroy(); 633 progress = null; 634 } 635 } 383 File files[] = (new File(directory)).listFiles(); 384 if(files != null) { 385 // Create a progress indicator. 386 ParsingProgress progress = new ParsingProgress(get("CDM.ClassifierManager.Parsing.Title"), get("CDM.ClassifierManager.Parsing.Message"), files.length); 387 for(int i = 0; i < files.length; i++) { 388 // We only want to check Perl Modules. 389 if(files[i].getName().endsWith(".pm")) { 390 loadClassifier(files[i]); 391 } 392 progress.inc(); 393 } 394 progress.dispose(); 395 progress.destroy(); 396 progress = null; 397 } 398 } 399 } 400 636 401 /** Parses a DOM tree model turning it into a Classifier and its associated arguments. 637 402 * @param root The <strong>Node</strong> at the root of the DOM model. … … 639 404 * @see org.greenstone.gatherer.cdm.Argument 640 405 */ 641 private Classifier parse (Node root) {406 private Classifier parseXML(Node root) { 642 407 Classifier classifier = new Classifier(); 643 408 String node_name = null; … … 648 413 String name = MSMUtils.getValue(node); 649 414 // We can save ourselves some processing time if a classifier with this name already exists in our manager. If so retrieve it and return it. 650 Classifier existing = get Classifier(name);415 Classifier existing = getBaseClassifier(name); 651 416 if(existing != null) { 652 417 return existing; … … 655 420 } 656 421 else if(node_name.equals("Desc")) { 657 classifier.setDesc (MSMUtils.getValue(node));422 classifier.setDescription(MSMUtils.getValue(node)); 658 423 } 659 424 // Parse the multitude of arguments. … … 671 436 } 672 437 else if(node_name.equals("Desc")) { 673 argument.setDesc (MSMUtils.getValue(det));438 argument.setDescription(MSMUtils.getValue(det)); 674 439 } 675 440 else if(node_name.equals("Type")) { … … 677 442 } 678 443 else if(node_name.equals("Default")) { 679 argument.setDefault (MSMUtils.getValue(det));444 argument.setDefaultValue(MSMUtils.getValue(det)); 680 445 } 681 446 else if(node_name.equals("List")) { … … 713 478 // A super classifier class. 714 479 else if(node_name.equals("ClasInfo")) { 715 Classifier super_classifier = parse (arg);480 Classifier super_classifier = parseXML(arg); 716 481 classifier.setSuper(super_classifier); 717 482 } … … 726 491 } 727 492 /** A class which provides controls for assigned and editing classifiers. */ 728 private class Control 729 extends JPanel { 493 private class ClassifierControl 494 extends JPanel 495 implements Control { 496 /** A combobox containing all of the known classifiers, including those that may have already been assigned. */ 497 private GComboBox classifier = null; 730 498 /** Button for adding classifiers. */ 731 499 private JButton add = null; 732 500 /** Button for configuring the selected classifier. */ 733 501 private JButton configure = null; 502 503 private JButton move_bottom_button; 504 505 private JButton move_down_button; 506 507 private JButton move_top_button; 508 509 private JButton move_up_button; 510 734 511 /** Button to remove the selected classifier. */ 735 512 private JButton remove = null; 736 /** A combobox containing all of the known classifiers, including those that may have already been assigned. */ 737 private JComboBox classifier = null; 513 738 514 /** A list of assigned classifiers. */ 739 515 private JList classifier_list = null; … … 745 521 * @see org.greenstone.gatherer.cdm.ClassifierManager.Control.RemoveListener 746 522 */ 747 public Control() { 748 Object classifiers[] = reserve.toArray(); 749 ArrayList classifier_model = new ArrayList(); 750 for(int i = 0; i < classifiers.length; i++) { 751 classifier_model.add(((Classifier)classifiers[i]).getName()); 752 } 753 // Now we add custom classifiers. 754 addCustomClassifiers(classifier_model); 755 Collections.sort(classifier_model); 523 public ClassifierControl() { 524 Collections.sort(library); 756 525 // Create 757 526 add = new JButton(get("Add")); … … 766 535 instructions.setRows(5); 767 536 instructions.setWrapStyleWord(true); 768 classifier = new JComboBox(classifier_model.toArray()); 769 classifier.setEditable(false); 537 538 classifier = new GComboBox(library.toArray()); 539 classifier.setBackgroundNonSelectionColor(Gatherer.config.getColor("coloring.editable", false)); 540 classifier.setBackgroundSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false)); 541 classifier.setEditable(true); 542 classifier.setSelectedIndex(0); 543 classifier.setTextNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_foreground", false)); 544 classifier.setTextSelectionColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false)); 545 770 546 JLabel classifier_label = new JLabel(get("Classifier")); 771 classifier_list = new JList( assigned);547 classifier_list = new JList(model); 772 548 classifier_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 773 549 JLabel classifier_list_label = new JLabel(get("Assigned")); … … 782 558 title.setOpaque(true); 783 559 JPanel temp = new JPanel(new BorderLayout()); 560 561 JPanel move_button_pane = new JPanel(); 562 563 move_bottom_button = new JButton(); 564 JLabel move_bottom_label = new JLabel(get("CDM.Move.Move_Bottom")); 565 move_bottom_label.setHorizontalAlignment(JLabel.CENTER); 566 move_bottom_label.setPreferredSize(LABEL_SIZE); 567 ImageIcon move_bottom_icon = Utility.getImage("arrow-bottom.gif"); 568 move_bottom_button.setLayout(new BorderLayout()); 569 move_bottom_button.add(new JLabel(move_bottom_icon), BorderLayout.WEST); 570 move_bottom_button.add(move_bottom_label, BorderLayout.CENTER); 571 move_bottom_button.add(new JLabel(move_bottom_icon), BorderLayout.EAST); 572 move_bottom_button.setMnemonic(KeyEvent.VK_B); 573 574 move_down_button = new JButton(); 575 JLabel move_down_label = new JLabel(get("CDM.Move.Move_Down")); 576 move_down_label.setHorizontalAlignment(JLabel.CENTER); 577 move_down_label.setPreferredSize(LABEL_SIZE); 578 ImageIcon move_down_icon = Utility.getImage("arrow-down.gif"); 579 move_down_button.setLayout(new BorderLayout()); 580 move_down_button.add(new JLabel(move_down_icon), BorderLayout.WEST); 581 move_down_button.add(move_down_label, BorderLayout.CENTER); 582 move_down_button.add(new JLabel(move_down_icon), BorderLayout.EAST); 583 move_down_button.setMnemonic(KeyEvent.VK_D); 584 585 move_top_button = new JButton(); 586 JLabel move_top_label = new JLabel(get("CDM.Move.Move_Top")); 587 move_top_label.setHorizontalAlignment(JLabel.CENTER); 588 move_top_label.setPreferredSize(LABEL_SIZE); 589 ImageIcon move_top_icon = Utility.getImage("arrow-top.gif"); 590 move_top_button.setLayout(new BorderLayout()); 591 move_top_button.add(new JLabel(move_top_icon), BorderLayout.WEST); 592 move_top_button.add(move_top_label, BorderLayout.CENTER); 593 move_top_button.add(new JLabel(move_top_icon), BorderLayout.EAST); 594 move_top_button.setMnemonic(KeyEvent.VK_T); 595 596 move_up_button = new JButton(); 597 JLabel move_up_label = new JLabel(get("CDM.Move.Move_Up")); 598 move_up_label.setHorizontalAlignment(JLabel.CENTER); 599 move_up_label.setPreferredSize(LABEL_SIZE); 600 ImageIcon move_up_icon = Utility.getImage("arrow-up.gif"); 601 move_up_button.setLayout(new BorderLayout()); 602 move_up_button.add(new JLabel(move_up_icon), BorderLayout.WEST); 603 move_up_button.add(move_up_label, BorderLayout.CENTER); 604 move_up_button.add(new JLabel(move_up_icon), BorderLayout.EAST); 605 move_up_button.setMnemonic(KeyEvent.VK_U); 606 784 607 // Listeners 785 608 add.addActionListener(new AddListener()); … … 788 611 classifier_list.addMouseListener(new ClickListener()); 789 612 classifier_list.addListSelectionListener(new ListListener()); 613 614 MoveListener ml = new MoveListener(); 615 move_bottom_button.addActionListener(ml); 616 move_down_button.addActionListener(ml); 617 move_top_button.addActionListener(ml); 618 move_up_button.addActionListener(ml); 790 619 // Layout 791 620 title.setBorder(BorderFactory.createEmptyBorder(0,0,2,0)); 621 792 622 instructions.setBorder(BorderFactory.createEmptyBorder(2,5,2,5)); 623 793 624 header_pane.setLayout(new BorderLayout()); 794 625 header_pane.add(title, BorderLayout.NORTH); 795 626 header_pane.add(new JScrollPane(instructions), BorderLayout.CENTER); 627 628 move_button_pane.setLayout(new GridLayout(4,1)); 629 move_button_pane.add(move_top_button); 630 move_button_pane.add(move_up_button); 631 move_button_pane.add(move_down_button); 632 move_button_pane.add(move_bottom_button); 633 796 634 classifier_list_label.setBorder(BorderFactory.createEmptyBorder(0,2,0,2)); 635 797 636 classifier_list_pane.setLayout(new BorderLayout()); 798 637 classifier_list_pane.add(classifier_list_label, BorderLayout.NORTH); 799 638 classifier_list_pane.add(new JScrollPane(classifier_list), BorderLayout.CENTER); 639 classifier_list_pane.add(move_button_pane, BorderLayout.EAST); 640 800 641 classifier_label.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); 642 801 643 classifier_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0)); 802 644 classifier_pane.setLayout(new GridLayout(1,2)); 803 645 classifier_pane.add(classifier_label); 804 646 classifier_pane.add(classifier); 647 805 648 button_pane.setLayout(new GridLayout(3,1)); 806 649 button_pane.add(add); 807 650 button_pane.add(configure); 808 651 button_pane.add(remove); 652 809 653 // Scope these mad bordering skillz. 810 654 temp.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,0,5,0), BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Controls")), BorderFactory.createEmptyBorder(2,2,2,2)))); 811 655 temp.add(classifier_pane, BorderLayout.NORTH); 812 656 temp.add(button_pane, BorderLayout.SOUTH); 657 813 658 central_pane.setLayout(new BorderLayout()); 814 659 central_pane.add(classifier_list_pane, BorderLayout.CENTER); 815 660 central_pane.add(temp, BorderLayout.SOUTH); 661 816 662 setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 817 663 setLayout(new BorderLayout()); … … 831 677 /** This method is overridden to ensure the instructions are scrolled to top, before the super classes updateUI() is called. 832 678 */ 833 public void updateUI() {679 public void gainFocus() { 834 680 if(instructions != null) { 835 681 instructions.setCaretPosition(0); 836 682 } 837 super.updateUI(); 838 } 839 /** Searches and adds a list of dynamically located CustomClassifiers. Note that the classes must be located under org.greenstone.gatherer.cdm.custom and have accompaning properties files which are used as dictionaries. 840 * @param classifier_model An <strong>ArrayList</strong> which will be used as the model for the combobox listing all known Classifiers. 841 */ 842 private void addCustomClassifiers(ArrayList classifier_model) { 843 //classifier_model.add("CustomAZList"); 844 // Search for classifiers under the org.greenstone.gatherer.cdm.custom directory. 845 File custom_directory = new File(Utility.BASE_DIR + "classes" + File.separator + "org" + File.separator + "greenstone" + File.separator + "gatherer" + File.separator + "cdm" + File.separator + "custom"); 846 if(custom_directory.exists()) { 847 File children[] = custom_directory.listFiles(); 848 for(int i = 0; i < children.length; i++) { 849 String temp = children[i].getName().toLowerCase(); 850 // There are a whole bunch of conditions about what files are custom classifier main classes. 851 if(temp.endsWith(".class") && temp.indexOf("$") == -1) { 852 // Determine the name of this custom classifier. 853 String name = children[i].getName(); 854 name = name.substring(0, name.indexOf(".")); 855 classifier_model.add(name); 856 } 857 } 858 } 859 // Search for any other CustomClassifiers within the jar file (if present) 860 File jar_file = new File(Utility.GLI_ARCHIVE); 861 if(jar_file.exists()) { 862 try { 863 JarFile jar = new JarFile(jar_file); 864 for(Enumeration entries = jar.entries(); entries.hasMoreElements(); ) { 865 String name = entries.nextElement().toString(); 866 if(name.startsWith("org/greenstone/gatherer/cdm/custom/") && name.endsWith(".class") && name.indexOf("$") == -1) { 867 name = name.substring(35, name.length() - 6); 868 if(!classifier_model.contains(name)) { 869 classifier_model.add(name); 870 } 871 } 872 name = null; 873 } 874 jar = null; 875 } 876 catch (Exception error) { 877 error.printStackTrace(); 878 } 879 } 880 jar_file = null; 881 } 683 } 684 685 public void loseFocus() { 686 } 687 882 688 /** This class listens for actions upon the add button in the controls, and if detected calls the assignClassifier() method. 883 689 */ 884 690 private class AddListener 885 691 implements ActionListener { … … 892 698 */ 893 699 public void actionPerformed(ActionEvent event) { 894 String name = (String)classifier.getSelectedItem(); 895 Classifier target = getClassifier(name); 896 Classifier classifier = null; 897 CustomClassifier custom_classifier = null; 898 if(target != null) { 899 classifier = target.copy(); 900 } 901 else { 902 // Try to retrieve custom classifier for name. 903 try { 904 Class custom_class = Class.forName("org.greenstone.gatherer.cdm.custom." + name); 905 custom_classifier = (CustomClassifier)custom_class.newInstance(); 906 custom_classifier.setGatherer(gatherer); 907 } 908 catch (Exception error) { 909 Gatherer.println("Error in ClassifierManager.AddListener.actionPerformed(): " + error); 910 Gatherer.printStackTrace(error); 911 912 } 913 // And if all else fails create a new classifier. 914 if(classifier == null && custom_classifier == null) { 915 classifier = new Classifier(name, "", null); 916 } 917 } 918 if(classifier != null) { 700 Object selected_object = classifier.getSelectedItem(); 701 // If there is something in the combobox, but we haven't registered a selection, then add the object and select it! 702 if(selected_object != null && classifier.getSelectedIndex() == -1) { 703 classifier.insertItemAt(selected_object, classifier.getItemCount()); 704 } 705 if(selected_object != null) { 706 // Create a new element in the DOM 707 Element element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.CLASSIFY_ELEMENT); 708 Classifier new_classifier = null; 709 if(selected_object instanceof Classifier) { 710 Classifier base_classifier = (Classifier) selected_object; 711 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, base_classifier.getName()); 712 new_classifier = new Classifier(element, base_classifier); 713 base_classifier = null; 714 } 715 else { 716 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, selected_object.toString()); 717 new_classifier = new Classifier(element, null); 718 } 719 element = null; 919 720 // Automatically chain to configuration. This ensures required arguments are filled out. 920 ArgumentConfiguration ac = new ArgumentConfiguration( gatherer, manager,classifier);721 ArgumentConfiguration ac = new ArgumentConfiguration(new_classifier); 921 722 if(ac.display()) { 922 assignClassifier(classifier); 923 } 924 ac.destroy(); 723 if(!model.contains(new_classifier)) { 724 assignClassifier(new_classifier); 725 classifier_list.setSelectedValue(new_classifier, true); 726 } 727 else { 728 JOptionPane.showMessageDialog(Gatherer.g_man, get("Classifier_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE); 729 } 730 } 925 731 ac = null; 926 } 927 // Custom classifier 928 else { 929 // Spawn a new thread to handle this, as custom_classifiers can be processor heavy. 930 CustomClassifierTask task = new CustomClassifierTask(custom_classifier); 931 task.start(); 732 new_classifier = null; 733 classifier.setSelectedIndex(0); 932 734 } 933 735 } … … 936 738 private class ClickListener 937 739 extends MouseAdapter { 938 939 940 740 /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt. 741 * @param event A <strong>MouseEvent</strong> containing information about the mouse click. 742 */ 941 743 public void mouseClicked(MouseEvent event) { 942 744 if(event.getClickCount() == 2 ) { 943 745 if(!classifier_list.isSelectionEmpty()) { 944 Object object = classifier_list.getSelectedValue(); 945 if(object instanceof Classifier) { 946 ArgumentConfiguration ac = new ArgumentConfiguration(gatherer, manager, (Classifier)object); 947 if(ac.display()) { 948 assigned.refresh(); 949 } 950 ac.destroy(); 951 ac = null; 746 Classifier classifier = (Classifier) classifier_list.getSelectedValue(); 747 ArgumentConfiguration ac = new ArgumentConfiguration(classifier); 748 if(ac.display()) { 749 refresh(classifier); 952 750 } 953 else if(object instanceof CustomClassifier) { 954 CustomClassifier cc = (CustomClassifier)object; 955 if(cc.display(true)) { 956 assigned.refresh(); 957 } 958 cc.hide(); // Remove gui prompt or else. 959 cc = null; 960 } 751 ac.destroy(); 752 ac = null; 961 753 } 962 754 } … … 975 767 public void actionPerformed(ActionEvent event) { 976 768 if(!classifier_list.isSelectionEmpty()) { 977 Object object = classifier_list.getSelectedValue(); 978 if(object instanceof Classifier) { 979 ArgumentConfiguration ac = new ArgumentConfiguration(gatherer, manager, (Classifier)object); 980 if(ac.display()) { 981 assigned.refresh(); 982 } 983 ac.destroy(); 984 ac = null; 985 } 986 else if(object instanceof CustomClassifier) { 987 CustomClassifier cc = (CustomClassifier)object; 988 if(cc.display(true)) { 989 assigned.refresh(); 990 } 991 cc.hide(); // Remove gui prompt or else. 992 cc = null; 993 } 994 } 995 } 996 } 997 998 private class CustomClassifierTask 999 extends Thread { 1000 1001 private CustomClassifier custom_classifier; 1002 1003 CustomClassifierTask(CustomClassifier custom_classifier) { 1004 this.custom_classifier = custom_classifier; 1005 } 1006 1007 public void run() { 1008 if(custom_classifier.display(true)) { 1009 assignClassifier(custom_classifier); 1010 } 1011 custom_classifier.hide(); // Remove gui prompt or else. 1012 custom_classifier = null; 769 Classifier classifier = (Classifier) classifier_list.getSelectedValue(); 770 ArgumentConfiguration ac = new ArgumentConfiguration(classifier); 771 if(ac.display()) { 772 refresh(classifier); 773 } 774 ac.destroy(); 775 ac = null; 776 } 1013 777 } 1014 778 } … … 1030 794 } 1031 795 } 796 797 /** 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. */ 798 private class MoveListener 799 implements ActionListener { 800 /** 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. 801 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action. 802 */ 803 public void actionPerformed(ActionEvent event) { 804 if(!classifier_list.isSelectionEmpty()) { 805 Object object = classifier_list.getSelectedValue(); 806 if(object instanceof Classifier) { 807 Classifier classifier = (Classifier) object; 808 if(event.getSource() == move_top_button) { 809 moveClassifier(classifier, true, true); 810 } 811 else if(event.getSource() == move_up_button) { 812 moveClassifier(classifier, true, false); 813 } 814 else if(event.getSource() == move_down_button) { 815 moveClassifier(classifier, false, false); 816 } 817 else { 818 moveClassifier(classifier, false, true); 819 } 820 classifier_list.setSelectedValue(classifier, true); 821 } 822 } 823 } 824 } 825 1032 826 /** This class listens for actions upon the remove button in the controls, and if detected calls the removeClassifier() method. 1033 827 */ … … 1041 835 public void actionPerformed(ActionEvent event) { 1042 836 if(!classifier_list.isSelectionEmpty()) { 1043 Object object = classifier_list.getSelectedValue(); 1044 if(object instanceof Classifier || object instanceof CustomClassifier) { 1045 removeClassifier(object); 837 Object [] objects = classifier_list.getSelectedValues(); 838 for(int i = 0; i < objects.length; i++) { 839 if(objects[i] instanceof Classifier) { 840 removeClassifier((Classifier)objects[i]); 841 } 1046 842 } 1047 843 } … … 1050 846 } 1051 847 } 1052 1053 1054 1055 1056 1057
Note:
See TracChangeset
for help on using the changeset viewer.