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