1   /*
2    *  Copyright (c) 1998-2004, The University of Sheffield.
3    *
4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
5    *  software, licenced under the GNU Library General Public License,
6    *  Version 2, June 1991 (in the distribution as file licence.html,
7    *  and also available at http://gate.ac.uk/gate/licence.html).
8    *
9    *  Valentin Tablan 02/10/2001
10   *
11   *  $Id: SerialControllerEditor.java,v 1.40 2004/08/06 16:08:25 valyt Exp $
12   *
13   */
14  
15  package gate.gui;
16  
17  import java.awt.Component;
18  import java.awt.Dimension;
19  import java.awt.event.*;
20  import java.text.NumberFormat;
21  import java.util.*;
22  
23  import javax.swing.*;
24  import javax.swing.border.TitledBorder;
25  import javax.swing.event.*;
26  import javax.swing.table.AbstractTableModel;
27  import javax.swing.table.TableCellRenderer;
28  
29  import gate.*;
30  import gate.creole.*;
31  import gate.event.*;
32  import gate.swing.*;
33  import gate.util.*;
34  
35  public class SerialControllerEditor extends AbstractVisualResource
36                                 implements CreoleListener, ControllerListener,
37                                            ActionsPublisher{
38  
39    public SerialControllerEditor() {
40  
41    }
42  
43    public void setTarget(Object target){
44      if(!(target instanceof SerialController))
45      throw new IllegalArgumentException(
46        "gate.gui.ApplicationViewer can only be used for serial controllers\n" +
47        target.getClass().toString() +
48        " is not a gate.creole.SerialController!");
49      if(controller != null) controller.removeControllerListener(this);
50      this.controller = (SerialController)target;
51      controller.addControllerListener(this);
52      analyserMode = controller instanceof SerialAnalyserController ||
53                     controller instanceof ConditionalSerialAnalyserController;
54      conditionalMode = controller instanceof ConditionalController;
55      
56      initLocalData();
57      initGuiComponents();
58      initListeners();
59    }//setController
60  
61  
62    public void setHandle(Handle handle) {
63      this.handle = handle;
64  
65  //    popup.addPopupMenuListener(new PopupMenuListener() {
66  //      public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
67  //        buildInternalMenus();
68  //        addMenu.setEnabled(addMenu.getItemCount() > 0);
69  //        removeMenu.setEnabled(removeMenu.getItemCount() > 0);
70  //      }
71  //      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
72  //      }
73  //      public void popupMenuCanceled(PopupMenuEvent e) {
74  //      }
75  //    });
76  
77      //register the listeners
78      if(handle instanceof StatusListener)
79        addStatusListener((StatusListener)handle);
80      if(handle instanceof ProgressListener)
81        addProgressListener((ProgressListener)handle);
82    }//setHandle
83  
84    public Resource init() throws ResourceInstantiationException{
85      super.init();
86      return this;
87    }//init
88  
89    protected void initLocalData() {
90      actionList = new ArrayList();
91      runAction = new RunAction();
92      //add the items to the popup
93      actionList.add(null);
94      actionList.add(runAction);
95    }//initLocalData
96  
97    protected void initGuiComponents() {
98      setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
99  
100 
101     JPanel topBox = new JPanel();
102     topBox.setLayout(new BoxLayout(topBox, BoxLayout.X_AXIS));
103     topBox.setAlignmentX(Component.LEFT_ALIGNMENT);
104 
105     loadedPRsTableModel = new LoadedPRsTableModel();
106     loadedPRsTable = new XJTable();
107     loadedPRsTable.setSortable(false);
108     loadedPRsTable.setModel(loadedPRsTableModel);
109 
110     loadedPRsTable.setDefaultRenderer(ProcessingResource.class,
111                                       new ResourceRenderer());
112 
113 //    loadedPRsTable.setIntercellSpacing(new Dimension(5, 5));
114     final int width1 = new JLabel("Loaded Processing resources").
115                 getPreferredSize().width + 10;
116     JScrollPane scroller = new JScrollPane(){
117       public Dimension getPreferredSize(){
118         Dimension dim = super.getPreferredSize();
119         dim.width = Math.max(dim.width, width1);
120         return dim;
121       }
122     };
123     scroller.getViewport().setView(loadedPRsTable);
124     scroller.setBorder(BorderFactory.
125                        createTitledBorder(BorderFactory.createEtchedBorder(),
126                                           " Loaded Processing resources "));
127 
128     topBox.add(scroller);
129     topBox.add(Box.createHorizontalGlue());
130 
131     addButon = new JButton(MainFrame.getIcon("right.gif"));
132     removeButton = new JButton(MainFrame.getIcon("left.gif"));
133 
134     Box buttonsBox =Box.createVerticalBox();
135     buttonsBox.add(Box.createVerticalGlue());
136     buttonsBox.add(addButon);
137     buttonsBox.add(Box.createVerticalStrut(5));
138     buttonsBox.add(removeButton);
139     buttonsBox.add(Box.createVerticalGlue());
140 
141     topBox.add(buttonsBox);
142     topBox.add(Box.createHorizontalGlue());
143 
144     memberPRsTableModel = new MemberPRsTableModel();
145     memberPRsTable = new XJTable();
146     memberPRsTable.setSortable(false);
147     memberPRsTable.setModel(memberPRsTableModel);
148     memberPRsTable.setDefaultRenderer(ProcessingResource.class,
149                                       new ResourceRenderer());
150     memberPRsTable.setDefaultRenderer(JLabel.class, new LabelRenderer());
151 //    memberPRsTable.setIntercellSpacing(new Dimension(5, 5));
152 
153     final int width2 = new JLabel("Selected Processing resources").
154                            getPreferredSize().width + 10;
155     scroller = new JScrollPane(){
156       public Dimension getPreferredSize(){
157         Dimension dim = super.getPreferredSize();
158         dim.width = Math.max(dim.width, width2);
159         return dim;
160       }
161     };
162     scroller.getViewport().setView(memberPRsTable);
163     scroller.setBorder(BorderFactory.
164                        createTitledBorder(BorderFactory.createEtchedBorder(),
165                                           " Selected Processing resources "));
166 
167 
168     topBox.add(scroller);
169 
170     moveUpButton = new JButton(MainFrame.getIcon("moveup.gif"));
171     moveDownButton = new JButton(MainFrame.getIcon("movedown.gif"));
172 
173     buttonsBox =Box.createVerticalBox();
174     buttonsBox.add(Box.createVerticalGlue());
175     buttonsBox.add(moveUpButton);
176     buttonsBox.add(Box.createVerticalStrut(5));
177     buttonsBox.add(moveDownButton);
178     buttonsBox.add(Box.createVerticalGlue());
179 
180     topBox.add(buttonsBox);
181     topBox.add(Box.createHorizontalGlue());
182 
183     add(topBox);
184 
185     if(conditionalMode){
186       strategyPanel = new JPanel();
187       strategyPanel.setLayout(new BoxLayout(strategyPanel, BoxLayout.X_AXIS));
188       strategyPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
189       runBtnGrp = new ButtonGroup();
190       yes_RunRBtn = new JRadioButton("Yes", true);
191       yes_RunRBtn.setHorizontalTextPosition(AbstractButton.LEFT);
192       runBtnGrp.add(yes_RunRBtn);
193       no_RunRBtn = new JRadioButton("No", false);
194       no_RunRBtn.setHorizontalTextPosition(AbstractButton.LEFT);
195       runBtnGrp.add(no_RunRBtn);
196       conditional_RunRBtn = new JRadioButton("If value of feature", false);
197       conditional_RunRBtn.setHorizontalTextPosition(AbstractButton.LEFT);
198       runBtnGrp.add(conditional_RunRBtn);
199 
200       featureNameTextField = new JTextField("", 25);
201       featureNameTextField.setMaximumSize(
202                            new Dimension(Integer.MAX_VALUE,
203                                          featureNameTextField.getPreferredSize().
204                                          height));
205       featureValueTextField = new JTextField("", 25);
206       featureValueTextField.setMaximumSize(
207                            new Dimension(Integer.MAX_VALUE,
208                                          featureValueTextField.getPreferredSize().
209                                          height));
210 
211       strategyPanel.add(new JLabel(MainFrame.getIcon("greenBall.gif")));
212       strategyPanel.add(yes_RunRBtn);
213       strategyPanel.add(Box.createHorizontalStrut(5));
214 
215       strategyPanel.add(new JLabel(MainFrame.getIcon("redBall.gif")));
216       strategyPanel.add(no_RunRBtn);
217       strategyPanel.add(Box.createHorizontalStrut(5));
218 
219       strategyPanel.add(new JLabel(MainFrame.getIcon("yellowBall.gif")));
220       strategyPanel.add(conditional_RunRBtn);
221       strategyPanel.add(Box.createHorizontalStrut(5));
222 
223       strategyPanel.add(featureNameTextField);
224       strategyPanel.add(Box.createHorizontalStrut(5));
225       strategyPanel.add(new JLabel("is"));
226       strategyPanel.add(Box.createHorizontalStrut(5));
227       strategyPanel.add(featureValueTextField);
228       strategyPanel.add(Box.createHorizontalStrut(5));
229       strategyBorder = BorderFactory.createTitledBorder(
230           BorderFactory.createEtchedBorder(),
231           " No processing resource selected... ");
232       strategyPanel.setBorder(strategyBorder);
233 
234       add(strategyPanel);
235     }//if conditional mode
236     if(analyserMode){
237       //we need to add the corpus combo
238       corpusCombo = new JComboBox(corpusComboModel = new CorporaComboModel());
239       corpusCombo.setRenderer(new ResourceRenderer());
240       corpusCombo.setMaximumSize(new Dimension(Integer.MAX_VALUE,
241                                                corpusCombo.getPreferredSize().
242                                                height));
243       Corpus corpus = null;
244       if(controller instanceof SerialAnalyserController){
245         corpus = ((SerialAnalyserController)controller).getCorpus();
246       }else if(controller instanceof ConditionalSerialAnalyserController){
247         corpus = ((ConditionalSerialAnalyserController)controller).getCorpus();
248       }else{
249         throw new GateRuntimeException("Controller editor in analyser mode " +
250                                        "but the target controller is not an " +
251                                        "analyser!");
252       }
253 
254       if(corpus != null){
255         corpusCombo.setSelectedItem(corpus);
256       }else{
257         if(corpusCombo.getModel().getSize() > 1) corpusCombo.setSelectedIndex(1);
258         else corpusCombo.setSelectedIndex(0);
259       }
260       JPanel horBox = new JPanel();
261       horBox.setLayout(new BoxLayout(horBox, BoxLayout.X_AXIS));
262       horBox.setAlignmentX(Component.LEFT_ALIGNMENT);
263       horBox.add(new JLabel("Corpus:"));
264       horBox.add(Box.createHorizontalStrut(5));
265       horBox.add(corpusCombo);
266       horBox.add(Box.createHorizontalStrut(5));
267       horBox.add(Box.createHorizontalGlue());
268       add(horBox);
269       JLabel warningLbl = new JLabel(
270         "<HTML>The <b>corpus</b> and <b>document</b> parameters are not " +
271         "available as they are automatically set by the controller!</HTML>");
272       warningLbl.setAlignmentX(java.awt.Component.LEFT_ALIGNMENT);
273       add(warningLbl);
274     }
275 
276     parametersPanel = new JPanel();
277     parametersPanel.setLayout(new BoxLayout(parametersPanel, BoxLayout.Y_AXIS));
278     parametersPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
279     parametersBorder = BorderFactory.createTitledBorder(
280                                       BorderFactory.createEtchedBorder(),
281                                       " No selected processing resource ");
282     parametersPanel.setBorder(parametersBorder);
283     parametersEditor = new ResourceParametersEditor();
284     parametersEditor.init(null, null);
285     parametersPanel.add(new JScrollPane(parametersEditor));
286     add(Box.createVerticalStrut(5));
287     add(parametersPanel);
288 
289 
290     add(Box.createVerticalStrut(5));
291     add(Box.createVerticalGlue());
292     JPanel horBox = new JPanel();
293     horBox.setLayout(new BoxLayout(horBox, BoxLayout.X_AXIS));
294     horBox.setAlignmentX(Component.LEFT_ALIGNMENT);
295     horBox.add(Box.createHorizontalGlue());
296     horBox.add(new JButton(runAction));
297     horBox.add(Box.createHorizontalStrut(10));
298     add(horBox);
299     add(Box.createVerticalStrut(10));
300 
301     addMenu = new XJMenu("Add");
302     removeMenu = new XJMenu("Remove");
303   }// initGuiComponents()
304 
305   protected void initListeners() {
306     Gate.getCreoleRegister().addCreoleListener(this);
307 
308     this.addMouseListener(new MouseAdapter() {
309       public void mouseClicked(MouseEvent e) {
310         if(SwingUtilities.isRightMouseButton(e)){
311           if(handle != null && handle.getPopup()!= null)
312             handle.getPopup().show(SerialControllerEditor.this, e.getX(), e.getY());
313         }
314       }
315     });
316 
317     addButon.addActionListener(new ActionListener() {
318       public void actionPerformed(ActionEvent e) {
319         int rows[] = loadedPRsTable.getSelectedRows();
320         if(rows == null || rows.length == 0){
321           JOptionPane.showMessageDialog(
322               SerialControllerEditor.this,
323               "Please select some components from the list of available components!\n" ,
324               "GATE", JOptionPane.ERROR_MESSAGE);
325         } else {
326           List actions = new ArrayList();
327           for(int i = 0; i < rows.length; i++) {
328             Action act =(Action)new AddPRAction((ProcessingResource)
329                                      loadedPRsTable.getValueAt(rows[i], 0));
330             if(act != null) actions.add(act);
331           }
332           Iterator actIter = actions.iterator();
333           while(actIter.hasNext()){
334             ((Action)actIter.next()).actionPerformed(null);
335           }
336         }
337       }
338     });
339 
340     removeButton.addActionListener(new ActionListener() {
341       public void actionPerformed(ActionEvent e) {
342         int rows[] = memberPRsTable.getSelectedRows();
343         if(rows == null || rows.length == 0){
344           JOptionPane.showMessageDialog(
345               SerialControllerEditor.this,
346               "Please select some components to be removed "+
347               "from the list of used components!\n" ,
348               "GATE", JOptionPane.ERROR_MESSAGE);
349         } else {
350           List actions = new ArrayList();
351           for(int i = 0; i < rows.length; i++){
352             Action act =(Action)new RemovePRAction((ProcessingResource)
353                                      memberPRsTable.getValueAt(rows[i], 1));
354             if(act != null) actions.add(act);
355           }
356           Iterator actIter = actions.iterator();
357           while(actIter.hasNext()){
358             ((Action)actIter.next()).actionPerformed(null);
359           }
360         }// else
361       }//  public void actionPerformed(ActionEvent e)
362     });
363 
364     moveUpButton.addActionListener(new ActionListener() {
365       public void actionPerformed(ActionEvent e) {
366         int rows[] = memberPRsTable.getSelectedRows();
367         if(rows == null || rows.length == 0){
368           JOptionPane.showMessageDialog(
369               SerialControllerEditor.this,
370               "Please select some components to be moved "+
371               "from the list of used components!\n" ,
372               "GATE", JOptionPane.ERROR_MESSAGE);
373         } else {
374           //we need to make sure the rows are sorted
375           Arrays.sort(rows);
376           //get the list of PRs
377           for(int i = 0; i < rows.length; i++){
378             int row = rows[i];
379             if(row > 0){
380               //move it up
381               ProcessingResource value = controller.remove(row);
382               controller.add(row - 1, value);
383             }
384           }
385 //          memberPRsTableModel.fireTableDataChanged();
386           //restore selection
387           for(int i = 0; i < rows.length; i++){
388             int newRow = -1;
389             if(rows[i] > 0) newRow = rows[i] - 1;
390             else newRow = rows[i];
391             memberPRsTable.addRowSelectionInterval(newRow, newRow);
392           }
393         }
394 
395       }//public void actionPerformed(ActionEvent e)
396     });
397 
398 
399     moveDownButton.addActionListener(new ActionListener() {
400       public void actionPerformed(ActionEvent e) {
401         int rows[] = memberPRsTable.getSelectedRows();
402         if(rows == null || rows.length == 0){
403           JOptionPane.showMessageDialog(
404               SerialControllerEditor.this,
405               "Please select some components to be moved "+
406               "from the list of used components!\n" ,
407               "GATE", JOptionPane.ERROR_MESSAGE);
408         } else {
409           //we need to make sure the rows are sorted
410           Arrays.sort(rows);
411           //get the list of PRs
412           for(int i = rows.length - 1; i >= 0; i--){
413             int row = rows[i];
414             if(row < controller.getPRs().size() -1){
415               //move it down
416               ProcessingResource value = controller.remove(row);
417               controller.add(row + 1, value);
418             }
419           }
420 //          memberPRsTableModel.fireTableDataChanged();
421           //restore selection
422           for(int i = 0; i < rows.length; i++){
423             int newRow = -1;
424             if(rows[i] < controller.getPRs().size() - 1) newRow = rows[i] + 1;
425             else newRow = rows[i];
426             memberPRsTable.addRowSelectionInterval(newRow, newRow);
427           }
428         }
429 
430       }//public void actionPerformed(ActionEvent e)
431     });
432 
433     loadedPRsTable.addMouseListener(new MouseAdapter() {
434       public void mouseClicked(MouseEvent e) {
435         int row = loadedPRsTable.rowAtPoint(e.getPoint());
436         //load modules on double click
437         ProcessingResource pr = (ProcessingResource)
438                                 loadedPRsTableModel.getValueAt(row, 0);
439         if(SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2){
440           new AddPRAction(pr).actionPerformed(null);
441         }else if(SwingUtilities.isRightMouseButton(e)){
442             JPopupMenu popup = new XJPopupMenu();
443             popup.add(new AddPRAction(pr){
444               {
445                 putValue(NAME, "Add \"" + this.pr.getName() +
446                                "\" to the \"" + controller.getName() +
447                                "\" application");
448               }
449             });
450             popup.show(loadedPRsTable, e.getPoint().x, e.getPoint().y);
451           }
452       }
453 
454       public void mousePressed(MouseEvent e) {
455       }
456 
457       public void mouseReleased(MouseEvent e) {
458       }
459 
460       public void mouseEntered(MouseEvent e) {
461       }
462 
463       public void mouseExited(MouseEvent e) {
464       }
465     });
466 
467     memberPRsTable.addMouseListener(new MouseAdapter() {
468       public void mouseClicked(MouseEvent e) {
469         final int row = memberPRsTable.rowAtPoint(e.getPoint());
470         if(row != -1){
471           //edit parameters on click
472           if(SwingUtilities.isLeftMouseButton(e) /*&& e.getClickCount() == 2*/){
473             ProcessingResource pr = (ProcessingResource)
474                                     memberPRsTableModel.getValueAt(row, 1);
475             selectPR(row);
476           }else if(SwingUtilities.isRightMouseButton(e)){
477             JPopupMenu popup = new XJPopupMenu();
478             popup.add(new AbstractAction("Edit parameters"){
479               public void actionPerformed(ActionEvent e){
480                 ProcessingResource pr = (ProcessingResource)
481                                         memberPRsTableModel.getValueAt(row, 1);
482                 selectPR(row);
483               }
484             });
485             popup.show(memberPRsTable, e.getPoint().x, e.getPoint().y);
486           }
487         }
488       }
489 
490       public void mousePressed(MouseEvent e) {
491       }
492 
493       public void mouseReleased(MouseEvent e) {
494       }
495 
496       public void mouseEntered(MouseEvent e) {
497       }
498 
499       public void mouseExited(MouseEvent e) {
500       }
501     });
502 
503     addMenu.addMenuListener(new MenuListener() {
504       public void menuCanceled(MenuEvent e) {
505 
506       }
507 
508       public void menuDeselected(MenuEvent e) {
509       }
510 
511       public void menuSelected(MenuEvent e) {
512         buildInternalMenus();
513       }
514     });
515 
516     removeMenu.addMenuListener(new MenuListener() {
517       public void menuCanceled(MenuEvent e) {
518       }
519 
520       public void menuDeselected(MenuEvent e) {
521       }
522 
523       public void menuSelected(MenuEvent e) {
524         buildInternalMenus();
525       }
526     });
527 
528     if(conditionalMode){
529       final ActionListener executionModeActionListener = new ActionListener() {
530         public void actionPerformed(ActionEvent e) {
531           if(selectedPRRunStrategy != null &&
532              selectedPRRunStrategy instanceof AnalyserRunningStrategy){
533             AnalyserRunningStrategy strategy =
534               (AnalyserRunningStrategy)selectedPRRunStrategy;
535             if(yes_RunRBtn.isSelected()){
536               strategy.setRunMode(RunningStrategy.RUN_ALWAYS);
537               featureNameTextField.setEditable(false);
538               featureValueTextField.setEditable(false);
539             }else if(no_RunRBtn.isSelected()){
540               strategy.setRunMode(RunningStrategy.RUN_NEVER);
541               featureNameTextField.setEditable(false);
542               featureValueTextField.setEditable(false);
543             }else if(conditional_RunRBtn.isSelected()){
544               strategy.setRunMode(RunningStrategy.RUN_CONDITIONAL);
545               featureNameTextField.setEditable(true);
546               featureValueTextField.setEditable(true);
547 
548               String str = featureNameTextField.getText();
549               strategy.setFeatureName(str == null || str.length()==0 ?
550                                       null : str);
551               str = featureValueTextField.getText();
552               strategy.setFeatureValue(str == null || str.length()==0 ?
553                                       null : str);
554             }
555           }
556           memberPRsTable.repaint();
557         }
558       };
559 
560       yes_RunRBtn.addActionListener(executionModeActionListener);
561 
562       no_RunRBtn.addActionListener(executionModeActionListener);
563 
564       conditional_RunRBtn.addActionListener(executionModeActionListener);
565 
566       featureNameTextField.getDocument().addDocumentListener(
567       new javax.swing.event.DocumentListener() {
568         public void insertUpdate(javax.swing.event.DocumentEvent e) {
569           changeOccured(e);
570         }
571 
572         public void removeUpdate(javax.swing.event.DocumentEvent e) {
573           changeOccured(e);
574         }
575 
576         public void changedUpdate(javax.swing.event.DocumentEvent e) {
577           changeOccured(e);
578         }
579 
580         protected void changeOccured(javax.swing.event.DocumentEvent e){
581           if(selectedPRRunStrategy != null &&
582              selectedPRRunStrategy instanceof AnalyserRunningStrategy){
583             AnalyserRunningStrategy strategy =
584               (AnalyserRunningStrategy)selectedPRRunStrategy;
585             strategy.setFeatureName(featureNameTextField.getText());
586           }
587         }
588       });
589 
590       featureValueTextField.getDocument().addDocumentListener(
591       new javax.swing.event.DocumentListener() {
592         public void insertUpdate(javax.swing.event.DocumentEvent e) {
593           changeOccured(e);
594         }
595 
596         public void removeUpdate(javax.swing.event.DocumentEvent e) {
597           changeOccured(e);
598         }
599 
600         public void changedUpdate(javax.swing.event.DocumentEvent e) {
601           changeOccured(e);
602         }
603 
604         protected void changeOccured(javax.swing.event.DocumentEvent e){
605           if(selectedPRRunStrategy != null &&
606              selectedPRRunStrategy instanceof AnalyserRunningStrategy){
607             AnalyserRunningStrategy strategy =
608               (AnalyserRunningStrategy)selectedPRRunStrategy;
609             strategy.setFeatureValue(featureValueTextField.getText());
610           }
611         }
612       });
613     }//if conditional
614     if(analyserMode){
615       corpusCombo.addPopupMenuListener(new PopupMenuListener() {
616                     public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
617                       corpusComboModel.fireDataChanged();
618                     }
619 
620                     public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
621                     }
622 
623                     public void popupMenuCanceled(PopupMenuEvent e) {
624                     }
625                   });
626     }
627   }//protected void initListeners()
628 
629 
630   public List getActions(){
631     return actionList;
632   }
633 
634   /**
635    * Cleans the internal data and prepares this object to be collected
636    */
637   public void cleanup(){
638     Gate.getCreoleRegister().removeCreoleListener(this);
639     controller.removeControllerListener(this);
640     controller = null;
641     progressListeners.clear();
642     statusListeners.clear();
643     parametersEditor.cleanup();
644     addMenu.removeAll();
645     removeMenu.removeAll();
646     handle = null;
647   }
648 
649   protected void buildInternalMenus(){
650     addMenu.removeAll();
651     Iterator prIter = Gate.getCreoleRegister().getPrInstances().iterator();
652     while(prIter.hasNext()){
653       ProcessingResource pr = (ProcessingResource)prIter.next();
654       if(Gate.getHiddenAttribute(pr.getFeatures())){
655         //ignore this resource
656       }else{
657         Action act = new AddPRAction(pr);
658         if(act.isEnabled()) addMenu.add(act);
659       }
660     }// while
661 
662     removeMenu.removeAll();
663     prIter = Gate.getCreoleRegister().getPrInstances().iterator();
664     while(prIter.hasNext()){
665       ProcessingResource pr = (ProcessingResource)prIter.next();
666       if(Gate.getHiddenAttribute(pr.getFeatures())){
667         //ignore this resource
668       }else{
669         Action act = new RemovePRAction(pr);
670         if(act.isEnabled()) removeMenu.add(act);
671       }
672     }// while
673   }
674 
675   /**
676    * Called when a PR has been selected in the memeber PRs table;
677    */
678   protected void selectPR(int index){
679     ProcessingResource pr = (ProcessingResource)
680                             ((java.util.List)controller.getPRs()).get(index);
681     showParamsEditor(pr);
682     selectedPR = pr;
683     if(conditionalMode){
684       strategyBorder.setTitle(" Run \"" + pr.getName() + "\"? ");
685       //update the state of the run strategy buttons
686       selectedPRRunStrategy = (RunningStrategy)
687                                  ((List)((ConditionalController)controller).
688                                           getRunningStrategies()).get(index);
689       int runMode = selectedPRRunStrategy.getRunMode();
690 
691       if(selectedPRRunStrategy instanceof AnalyserRunningStrategy){
692         yes_RunRBtn.setEnabled(true);
693         no_RunRBtn.setEnabled(true);
694         conditional_RunRBtn.setEnabled(true);
695 
696         featureNameTextField.setText(
697               ((AnalyserRunningStrategy)selectedPRRunStrategy).
698               getFeatureName());
699         featureValueTextField.setText(
700               ((AnalyserRunningStrategy)selectedPRRunStrategy).
701               getFeatureValue());
702       }else{
703         yes_RunRBtn.setEnabled(false);
704         no_RunRBtn.setEnabled(false);
705         conditional_RunRBtn.setEnabled(false);
706 
707         featureNameTextField.setText("");
708         featureValueTextField.setText("");
709       }
710 
711       featureNameTextField.setEditable(false);
712       featureValueTextField.setEditable(false);
713 
714       switch(selectedPRRunStrategy.getRunMode()){
715         case RunningStrategy.RUN_ALWAYS:{
716           yes_RunRBtn.setSelected(true);
717           break;
718         }
719 
720         case RunningStrategy.RUN_NEVER:{
721           no_RunRBtn.setSelected(true);
722           break;
723         }
724 
725         case RunningStrategy.RUN_CONDITIONAL:{
726           conditional_RunRBtn.setSelected(true);
727           if(selectedPRRunStrategy instanceof AnalyserRunningStrategy){
728             featureNameTextField.setEditable(true);
729             featureValueTextField.setEditable(true);
730           }
731           break;
732         }
733       }//switch
734     }
735   }
736 
737   /**
738    * Stops the current edits for parameters; sets the paarmeters for the
739    * resource currently being edited and diplays the editor for the new
740    * resource
741    * @param pr the new resource
742    */
743   protected void showParamsEditor(ProcessingResource pr){
744     try{
745       if(parametersEditor.getResource() != null) parametersEditor.setParameters();
746     }catch(ResourceInstantiationException rie){
747       JOptionPane.showMessageDialog(
748           SerialControllerEditor.this,
749           "Failed to set parameters for \"" + pr.getName() +"\"!\n" ,
750           "GATE", JOptionPane.ERROR_MESSAGE);
751       rie.printStackTrace(Err.getPrintWriter());
752     }
753 
754     if(pr != null){
755       ResourceData rData = (ResourceData)Gate.getCreoleRegister().
756                                          get(pr.getClass().getName());
757 
758       parametersBorder.setTitle(" Parameters for the \"" + pr.getName() +
759                                 "\" " + rData.getName() + " ");
760 
761       //this is a list of lists
762       List parameters = rData.getParameterList().getRuntimeParameters();
763 
764       if(analyserMode){
765         //remove corpus and document
766         //create a new list so we don't change the one from CreoleReg.
767         List newParameters = new ArrayList();
768         Iterator pDisjIter = parameters.iterator();
769         while(pDisjIter.hasNext()){
770           List aDisjunction = (List)pDisjIter.next();
771           List newDisjunction = new ArrayList(aDisjunction);
772           Iterator internalParIter = newDisjunction.iterator();
773           while(internalParIter.hasNext()){
774             Parameter parameter = (Parameter)internalParIter.next();
775             if(parameter.getName().equals("corpus") ||
776                parameter.getName().equals("document")) internalParIter.remove();
777           }
778           if(!newDisjunction.isEmpty()) newParameters.add(newDisjunction);
779         }
780         parametersEditor.init(pr, newParameters);
781       }else{
782         parametersEditor.init(pr, parameters);
783       }
784     }else{
785       parametersBorder.setTitle("No selected processing resource");
786       parametersEditor.init(null, null);
787     }
788     SerialControllerEditor.this.validate();
789     SerialControllerEditor.this.repaint(100);
790   }
791 
792   //CreoleListener implementation
793   public void resourceLoaded(CreoleEvent e) {
794     if(Gate.getHiddenAttribute(e.getResource().getFeatures())) return;
795     if(e.getResource() instanceof ProcessingResource){
796       loadedPRsTableModel.fireTableDataChanged();
797       memberPRsTableModel.fireTableDataChanged();
798 //      repaint(100);
799     }else if(e.getResource() instanceof LanguageResource){
800       if(e.getResource() instanceof Corpus && analyserMode){
801         corpusComboModel.fireDataChanged();
802       }
803     }
804   }// public void resourceLoaded
805 
806   public void resourceUnloaded(CreoleEvent e) {
807     if(Gate.getHiddenAttribute(e.getResource().getFeatures())) return;
808     if(e.getResource() instanceof ProcessingResource){
809       ProcessingResource pr = (ProcessingResource)e.getResource();
810       if(controller.getPRs().contains(pr)){
811         new RemovePRAction(pr).actionPerformed(null);
812       }
813       loadedPRsTableModel.fireTableDataChanged();
814       memberPRsTableModel.fireTableDataChanged();
815 //      repaint(100);
816     }
817   }//public void resourceUnloaded(CreoleEvent e)
818 
819   public void resourceRenamed(Resource resource, String oldName,
820                               String newName){
821     if(Gate.getHiddenAttribute(resource.getFeatures())) return;
822     if(resource instanceof ProcessingResource){
823       repaint(100);
824     }
825   }
826 
827   public void datastoreOpened(CreoleEvent e) {
828   }
829   public void datastoreCreated(CreoleEvent e) {
830   }
831   public void datastoreClosed(CreoleEvent e) {
832   }
833   public synchronized void removeStatusListener(StatusListener l) {
834     if (statusListeners != null && statusListeners.contains(l)) {
835       Vector v = (Vector) statusListeners.clone();
836       v.removeElement(l);
837       statusListeners = v;
838     }
839   }
840   
841   /* (non-Javadoc)
842    * @see gate.event.ControllerListener#resourceAdded(gate.event.ControllerEvent)
843    */
844   public void resourceAdded(ControllerEvent evt){
845     loadedPRsTableModel.fireTableDataChanged();
846     memberPRsTableModel.fireTableDataChanged();
847 
848   }
849   
850   /* (non-Javadoc)
851    * @see gate.event.ControllerListener#resourceRemoved(gate.event.ControllerEvent)
852    */
853   public void resourceRemoved(ControllerEvent evt){
854     loadedPRsTableModel.fireTableDataChanged();
855     memberPRsTableModel.fireTableDataChanged();
856   }
857   
858   
859   
860   public synchronized void addStatusListener(StatusListener l) {
861     Vector v = statusListeners == null ? new Vector(2) :
862                                   (Vector) statusListeners.clone();
863     if (!v.contains(l)) {
864       v.addElement(l);
865       statusListeners = v;
866     }
867   }
868 
869 
870 
871   /**
872    * Table model for all the loaded processing resources that are not part of
873    * the controller.
874    */
875   class LoadedPRsTableModel extends AbstractTableModel{
876     public int getRowCount(){
877       List loadedPRs = new ArrayList(Gate.getCreoleRegister().getPrInstances());
878       loadedPRs.removeAll(controller.getPRs());
879       Iterator prsIter = loadedPRs.iterator();
880       while(prsIter.hasNext()){
881         ProcessingResource aPR = (ProcessingResource)prsIter.next();
882         if(Gate.getHiddenAttribute(aPR.getFeatures())) prsIter.remove();
883       }
884 
885       return loadedPRs.size();
886     }
887 
888     public Object getValueAt(int row, int column){
889       List loadedPRs = new ArrayList(Gate.getCreoleRegister().getPrInstances());
890       loadedPRs.removeAll(controller.getPRs());
891       Iterator prsIter = loadedPRs.iterator();
892       while(prsIter.hasNext()){
893         ProcessingResource aPR = (ProcessingResource)prsIter.next();
894         if(Gate.getHiddenAttribute(aPR.getFeatures())) prsIter.remove();
895       }
896 
897       Collections.sort(loadedPRs, nameComparator);
898       ProcessingResource pr = (ProcessingResource)loadedPRs.get(row);
899       switch(column){
900         case 0 : return pr;
901         case 1 : {
902           ResourceData rData = (ResourceData)Gate.getCreoleRegister().
903                                     get(pr.getClass().getName());
904           if(rData == null) return pr.getClass();
905           else return rData.getName();
906         }
907         default: return null;
908       }
909     }
910 
911     public int getColumnCount(){
912       return 2;
913     }
914 
915     public String getColumnName(int columnIndex){
916       switch(columnIndex){
917         case 0 : return "Name";
918         case 1 : return "Type";
919         default: return "?";
920       }
921     }
922 
923     public Class getColumnClass(int columnIndex){
924       switch(columnIndex){
925         case 0 : return ProcessingResource.class;
926         case 1 : return String.class;
927         default: return Object.class;
928       }
929     }
930 
931     public boolean isCellEditable(int rowIndex, int columnIndex){
932       return false;
933     }
934 
935     public void setValueAt(Object aValue, int rowIndex, int columnIndex){
936     }
937     NameComparator nameComparator = new NameComparator();
938   }//protected class LoadedPRsTableModel extends AbstractTableModel
939 
940   /**
941    * A model for a combobox containing the loaded corpora in the system
942    */
943   protected class CorporaComboModel extends AbstractListModel
944                                   implements ComboBoxModel{
945     public int getSize(){
946       //get all corpora regardless of their actual type
947       java.util.List loadedCorpora = null;
948       try{
949         loadedCorpora = Gate.getCreoleRegister().
950                                getAllInstances("gate.Corpus");
951       }catch(GateException ge){
952         ge.printStackTrace(Err.getPrintWriter());
953       }
954 
955       return loadedCorpora == null ? 1 : loadedCorpora.size() + 1;
956     }
957 
958     public Object getElementAt(int index){
959       if(index == 0) return "<none>";
960       else{
961         //get all corpora regardless of their actual type
962         java.util.List loadedCorpora = null;
963         try{
964           loadedCorpora = Gate.getCreoleRegister().
965                                  getAllInstances("gate.Corpus");
966         }catch(GateException ge){
967           ge.printStackTrace(Err.getPrintWriter());
968         }
969         return loadedCorpora == null? "" : loadedCorpora.get(index - 1);
970       }
971     }
972 
973     //use the controller for data caching
974     public void setSelectedItem(Object anItem){
975       if(controller instanceof SerialAnalyserController)
976       ((SerialAnalyserController)controller).
977         setCorpus((Corpus)(anItem.equals("<none>") ? null : anItem));
978       else if(controller instanceof ConditionalSerialAnalyserController)
979       ((ConditionalSerialAnalyserController)controller).
980         setCorpus((Corpus)(anItem.equals("<none>") ? null : anItem));
981     }
982 
983     public Object getSelectedItem(){
984       Corpus corpus = null;
985       if(controller instanceof SerialAnalyserController){
986         corpus = ((SerialAnalyserController)controller).getCorpus();
987       }else if(controller instanceof ConditionalSerialAnalyserController){
988         corpus = ((ConditionalSerialAnalyserController)controller).getCorpus();
989       }else{
990         throw new GateRuntimeException("Controller editor in analyser mode " +
991                                        "but the target controller is not an " +
992                                        "analyser!");
993       }
994       return (corpus == null ? (Object)"<none>" : (Object)corpus);
995     }
996 
997     void fireDataChanged(){
998       fireContentsChanged(this, 0, getSize());
999     }
1000  }
1001
1002  /**
1003   *  Renders JLabel by simply displaying them
1004   */
1005  class LabelRenderer implements TableCellRenderer{
1006    public Component getTableCellRendererComponent(JTable table,
1007                                                   Object value,
1008                                                   boolean isSelected,
1009                                                   boolean hasFocus,
1010                                                   int row,
1011                                                   int column){
1012      return (JLabel) value;
1013    }
1014  }
1015
1016  /**
1017   * Table model for all the processing resources in the controller.
1018   */
1019  class MemberPRsTableModel extends AbstractTableModel{
1020    MemberPRsTableModel(){
1021      green = new JLabel(MainFrame.getIcon("greenBall.gif"));
1022      red = new JLabel(MainFrame.getIcon("redBall.gif"));
1023      yellow = new JLabel(MainFrame.getIcon("yellowBall.gif"));
1024    }
1025    public int getRowCount(){
1026      return controller.getPRs().size();
1027    }
1028
1029    public Object getValueAt(int row, int column){
1030      ProcessingResource pr = (ProcessingResource)
1031                              ((List)controller.getPRs()).get(row);
1032      switch(column){
1033        case 0 : {
1034          if(conditionalMode){
1035            RunningStrategy strategy = (RunningStrategy)
1036                                 ((List)((ConditionalController)controller).
1037                                          getRunningStrategies()).get(row);
1038            switch(strategy.getRunMode()){
1039              case RunningStrategy.RUN_ALWAYS : return green;
1040              case RunningStrategy.RUN_NEVER : return red;
1041              case RunningStrategy.RUN_CONDITIONAL : return yellow;
1042            }
1043          }
1044          return green;
1045        }
1046        case 1 : return pr;
1047        case 2 : {
1048          ResourceData rData = (ResourceData)Gate.getCreoleRegister().
1049                                    get(pr.getClass().getName());
1050          if(rData == null) return pr.getClass();
1051          else return rData.getName();
1052        }
1053        default: return null;
1054      }
1055    }
1056
1057    public int getColumnCount(){
1058      return 3;
1059    }
1060
1061    public String getColumnName(int columnIndex){
1062      switch(columnIndex){
1063        case 0 : return "!";
1064        case 1 : return "Name";
1065//        case 1 : return "!";
1066        case 2 : return "Type";
1067        default: return "?";
1068      }
1069    }
1070
1071    public Class getColumnClass(int columnIndex){
1072      switch(columnIndex){
1073        case 0 : return JLabel.class;
1074        case 1 : return ProcessingResource.class;
1075//        case 1 : return Boolean.class;
1076        case 2 : return String.class;
1077        default: return Object.class;
1078      }
1079    }
1080
1081    public boolean isCellEditable(int rowIndex, int columnIndex){
1082      return false;
1083    }
1084
1085    public void setValueAt(Object aValue, int rowIndex, int columnIndex){
1086    }
1087
1088    protected JLabel green, red, yellow;
1089  }//protected class MemeberPRsTableModel extends AbstractTableModel
1090
1091  /** Adds a PR to the controller*/
1092  class AddPRAction extends AbstractAction {
1093    AddPRAction(ProcessingResource aPR){
1094      super(aPR.getName());
1095      this.pr = aPR;
1096      setEnabled(!controller.getPRs().contains(aPR));
1097    }
1098
1099    public void actionPerformed(ActionEvent e){
1100      controller.add(pr);
1101//      loadedPRsTableModel.fireTableDataChanged();
1102//      memberPRsTableModel.fireTableDataChanged();
1103//      SerialControllerEditor.this.validate();
1104//      SerialControllerEditor.this.repaint(100);
1105    }
1106
1107    ProcessingResource pr;
1108  }
1109
1110  /** Removes a PR from the controller*/
1111  class RemovePRAction extends AbstractAction {
1112    RemovePRAction(ProcessingResource pr){
1113      super(pr.getName());
1114      this.pr = pr;
1115      setEnabled(controller.getPRs().contains(pr));
1116    }
1117
1118    public void actionPerformed(ActionEvent e){
1119      if(controller.remove(pr)){
1120//        loadedPRsTableModel.fireTableDataChanged();
1121//        memberPRsTableModel.fireTableDataChanged();
1122        if(parametersEditor.getResource() == pr){
1123          parametersEditor.init(null, null);
1124          parametersBorder.setTitle("No selected processing resource");
1125        }
1126//        SerialControllerEditor.this.validate();
1127//        SerialControllerEditor.this.repaint(100);
1128      }
1129    }
1130
1131    ProcessingResource pr;
1132  }
1133
1134
1135  /** Runs the Application*/
1136  class RunAction extends AbstractAction {
1137    RunAction(){
1138      super("Run");
1139    }
1140
1141    public void actionPerformed(ActionEvent e){
1142      Runnable runnable = new Runnable(){
1143        public void run(){
1144          //stop editing the parameters
1145          try{
1146            parametersEditor.setParameters();
1147          }catch(ResourceInstantiationException rie){
1148            JOptionPane.showMessageDialog(
1149              SerialControllerEditor.this,
1150              "Could not set parameters for the \"" +
1151              parametersEditor.getResource().getName() +
1152              "\" processing resource:\nSee \"Messages\" tab for details!",
1153              "GATE", JOptionPane.ERROR_MESSAGE);
1154              rie.printStackTrace(Err.getPrintWriter());
1155              return;
1156          }
1157
1158          if(analyserMode){
1159            //set the corpus
1160            Object value = corpusCombo.getSelectedItem();
1161            Corpus corpus = value.equals("<none>") ? null : (Corpus)value;
1162            if(corpus == null){
1163              JOptionPane.showMessageDialog(
1164                SerialControllerEditor.this,
1165                "No corpus provided!\n" +
1166                "Please select a corpus and try again!",
1167                "GATE", JOptionPane.ERROR_MESSAGE);
1168              return;
1169            }
1170            if(controller instanceof SerialAnalyserController)
1171              ((SerialAnalyserController)controller).setCorpus(corpus);
1172            else if(controller instanceof ConditionalSerialAnalyserController)
1173              ((ConditionalSerialAnalyserController)controller).setCorpus(corpus);
1174          }
1175          //check the runtime parameters
1176          List badPRs;
1177          try{
1178            badPRs = controller.getOffendingPocessingResources();
1179          }catch(ResourceInstantiationException rie){
1180            JOptionPane.showMessageDialog(
1181              SerialControllerEditor.this,
1182              "Could not check runtime parameters for " +
1183              "the processing resources:\n" + rie.toString(),
1184              "GATE", JOptionPane.ERROR_MESSAGE);
1185            return;
1186          }
1187          if(badPRs != null && !badPRs.isEmpty()){
1188            //we know what PRs have problems so it would be nice to show
1189            //them in red or something
1190            JOptionPane.showMessageDialog(
1191              SerialControllerEditor.this,
1192              "Some required runtime parameters are not set!",
1193              "GATE", JOptionPane.ERROR_MESSAGE);
1194            return;
1195          }
1196
1197          //set the listeners
1198          StatusListener sListener = new InternalStatusListener();
1199          ProgressListener pListener = new InternalProgressListener();
1200
1201          controller.addStatusListener(sListener);
1202          controller.addProgressListener(pListener);
1203
1204          Gate.setExecutable(controller);
1205
1206          MainFrame.lockGUI("Running " + controller.getName() + "...");
1207          //execute the thing
1208          long startTime = System.currentTimeMillis();
1209          fireStatusChanged("Running " +
1210                            controller.getName());
1211          fireProgressChanged(0);
1212
1213          try {
1214            controller.execute();
1215          }catch(ExecutionInterruptedException eie){
1216            MainFrame.unlockGUI();
1217            JOptionPane.showMessageDialog(
1218              SerialControllerEditor.this,
1219              "Interrupted!\n" + eie.toString(),
1220              "GATE", JOptionPane.ERROR_MESSAGE);
1221          }catch(ExecutionException ee) {
1222            ee.printStackTrace(Err.getPrintWriter());
1223            MainFrame.unlockGUI();
1224            JOptionPane.showMessageDialog(
1225              SerialControllerEditor.this,
1226              "Execution error while running \"" + controller.getName() +
1227              "\" :\nSee \"Messages\" tab for details!",
1228              "GATE", JOptionPane.ERROR_MESSAGE);
1229          }catch(Exception e){
1230            MainFrame.unlockGUI();
1231            JOptionPane.showMessageDialog(SerialControllerEditor.this,
1232                                          "Unhandled execution error!\n " +
1233                                          "See \"Messages\" tab for details!",
1234                                          "GATE", JOptionPane.ERROR_MESSAGE);
1235            e.printStackTrace(Err.getPrintWriter());
1236          }finally{
1237            MainFrame.unlockGUI();
1238            Gate.setExecutable(null);
1239          }//catch
1240
1241          //remove the listeners
1242          controller.removeStatusListener(sListener);
1243          controller.removeProgressListener(pListener);
1244
1245          long endTime = System.currentTimeMillis();
1246          fireProcessFinished();
1247          fireStatusChanged(controller.getName() +
1248                            " run in " +
1249                            NumberFormat.getInstance().format(
1250                            (double)(endTime - startTime) / 1000) + " seconds");
1251        }
1252      };
1253      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
1254                                 runnable,
1255                                 "ApplicationViewer1");
1256      thread.setPriority(Thread.MIN_PRIORITY);
1257      thread.start();
1258    }//public void actionPerformed(ActionEvent e)
1259  }//class RunAction
1260
1261  /**
1262   * A simple progress listener used to forward the events upstream.
1263   */
1264  protected class InternalProgressListener implements ProgressListener{
1265    public void progressChanged(int i){
1266      fireProgressChanged(i);
1267    }
1268
1269    public void processFinished(){
1270      fireProcessFinished();
1271    }
1272  }//InternalProgressListener
1273
1274  /**
1275   * A simple status listener used to forward the events upstream.
1276   */
1277  protected class InternalStatusListener implements StatusListener{
1278    public void statusChanged(String message){
1279      fireStatusChanged(message);
1280    }
1281  }//InternalStatusListener
1282
1283
1284
1285  /** The controller this editor edits */
1286  protected SerialController controller;
1287
1288  /** The {@link Handle} that created this view */
1289  protected Handle handle;
1290
1291  /**
1292   * The list of actions provided by this editor
1293   */
1294  protected List actionList;
1295  /**
1296   * Contains all the PRs loaded in the sytem that are not already part of the
1297   * serial controller
1298   */
1299  protected XJTable loadedPRsTable;
1300
1301  /**
1302   * model for the {@link #loadedPRsTable} JTable.
1303   */
1304  protected LoadedPRsTableModel loadedPRsTableModel;
1305
1306  /**
1307   * Displays the PRs in the controller
1308   */
1309  protected XJTable memberPRsTable;
1310
1311  /** model for {@link #memberPRsTable}*/
1312  protected MemberPRsTableModel memberPRsTableModel;
1313
1314  /** Adds one or more PR(s) to the controller*/
1315  protected JButton addButon;
1316
1317  /** Removes one or more PR(s) from the controller*/
1318  protected JButton removeButton;
1319
1320  /** Moves the module up in the controller list*/
1321  protected JButton moveUpButton;
1322
1323  /** Moves the module down in the controller list*/
1324  protected JButton moveDownButton;
1325
1326  /** A component for editing the parameters of the currently selected PR*/
1327  protected ResourceParametersEditor parametersEditor;
1328
1329  /** A JPanel containing the {@link #parametersEditor}*/
1330  protected JPanel parametersPanel;
1331
1332  /** A border for the {@link #parametersPanel} */
1333  protected TitledBorder parametersBorder;
1334
1335
1336  /** A JPanel containing the running strategy options*/
1337  protected JPanel strategyPanel;
1338
1339  /** A border for the running strategy options box */
1340  protected TitledBorder strategyBorder;
1341
1342  /**
1343   * Button for run always.
1344   */
1345  protected JRadioButton yes_RunRBtn;
1346
1347  /**
1348   * Button for never run.
1349   */
1350  protected JRadioButton no_RunRBtn;
1351
1352  /**
1353   * Button for conditional run.
1354   */
1355  protected JRadioButton conditional_RunRBtn;
1356
1357  /**
1358   * The group for run strategy buttons;
1359   */
1360  protected ButtonGroup runBtnGrp;
1361
1362  /**
1363   * Text field for the feature name for conditional run.
1364   */
1365  protected JTextField featureNameTextField;
1366
1367  /**
1368   * Text field for the feature value for conditional run.
1369   */
1370  protected JTextField featureValueTextField;
1371
1372  /**
1373   * A combobox that allows selection of a corpus from the list of loaded
1374   * corpora.
1375   */
1376  protected JComboBox corpusCombo;
1377
1378  protected CorporaComboModel corpusComboModel;
1379
1380  /**The "Add PR" menu; part of the popup menu*/
1381  protected JMenu addMenu;
1382
1383  /**The "Remove PR" menu; part of the popup menu*/
1384  protected JMenu removeMenu;
1385
1386  /** Action that runs the application*/
1387  protected RunAction runAction;
1388
1389  /**
1390   * Is the controller displayed an analyser controller?
1391   */
1392  protected boolean analyserMode = false;
1393
1394  /**
1395   * Is the controller displayed conditional?
1396   */
1397  protected boolean conditionalMode = false;
1398
1399  /**
1400   * The PR currently selected (having its parameters set)
1401   */
1402  protected ProcessingResource selectedPR = null;
1403
1404  /**
1405   * The running strategy for the selected PR.
1406   */
1407  protected RunningStrategy selectedPRRunStrategy = null;
1408
1409  private transient Vector statusListeners;
1410  private transient Vector progressListeners;
1411
1412
1413
1414  protected void fireStatusChanged(String e) {
1415    if (statusListeners != null) {
1416      Vector listeners = statusListeners;
1417      int count = listeners.size();
1418      for (int i = 0; i < count; i++) {
1419        ((StatusListener) listeners.elementAt(i)).statusChanged(e);
1420      }
1421    }
1422  }
1423  public synchronized void removeProgressListener(ProgressListener l) {
1424    if (progressListeners != null && progressListeners.contains(l)) {
1425      Vector v = (Vector) progressListeners.clone();
1426      v.removeElement(l);
1427      progressListeners = v;
1428    }
1429  }
1430  public synchronized void addProgressListener(ProgressListener l) {
1431    Vector v = progressListeners == null ? new Vector(2) : (Vector) progressListeners.clone();
1432    if (!v.contains(l)) {
1433      v.addElement(l);
1434      progressListeners = v;
1435    }
1436  }
1437  protected void fireProgressChanged(int e) {
1438    if (progressListeners != null) {
1439      Vector listeners = progressListeners;
1440      int count = listeners.size();
1441      for (int i = 0; i < count; i++) {
1442        ((ProgressListener) listeners.elementAt(i)).progressChanged(e);
1443      }
1444    }
1445  }
1446  protected void fireProcessFinished() {
1447    if (progressListeners != null) {
1448      Vector listeners = progressListeners;
1449      int count = listeners.size();
1450      for (int i = 0; i < count; i++) {
1451        ((ProgressListener) listeners.elementAt(i)).processFinished();
1452      }
1453    }
1454  }
1455  }//SerialControllerEditor
1456