| SerialControllerEditor |

    1   /*
    2    *  Copyright (c) 1998-2001, 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.17 2001/11/15 14:21:14 valyt Exp $
    12   *
    13   */
    14
    15  package gate.gui;
    16
    17  import gate.creole.*;
    18  import gate.*;
    19  import gate.swing.*;
    20  import gate.util.*;
    21  import gate.event.*;
    22
    23
    24  import javax.swing.*;
    25  import javax.swing.table.*;
    26  import javax.swing.event.*;
    27  import javax.swing.border.*;
    28  import java.awt.event.*;
    29  import java.awt.Dimension;
    30  import java.awt.Component;
    31  import java.text.NumberFormat;
    32  import java.util.*;
    33
    34  public class SerialControllerEditor extends AbstractVisualResource
    35                                 implements CreoleListener{
    36
    37    public SerialControllerEditor() {
    38    }
    39
    40    public void setTarget(Object target){
    41      if(!(target instanceof SerialController))
    42      throw new IllegalArgumentException(
    43        "gate.gui.ApplicationViewer can only be used for serial controllers\n" +
    44        target.getClass().toString() +
    45        " is not a gate.creole.SerialController!");
    46      this.controller = (SerialController)target;
    47      analyserMode = controller instanceof SerialAnalyserController;
    48      initLocalData();
    49      initGuiComponents();
    50      initListeners();
    51    }//setController
    52
    53
    54    public void setHandle(Handle handle) {
    55      this.handle = handle;
    56      //add the items to the popup
    57      JPopupMenu popup = handle.getPopup();
    58      popup.addSeparator();
    59      popup.add(runAction);
    60      popup.addSeparator();
    61      popup.add(addMenu);
    62      popup.add(removeMenu);
    63
    64      //register the listeners
    65      if(handle instanceof StatusListener)
    66        addStatusListener((StatusListener)handle);
    67      if(handle instanceof ProgressListener)
    68        addProgressListener((ProgressListener)handle);
    69    }//setHandle
    70
    71    public Resource init() throws ResourceInstantiationException{
    72      super.init();
    73      return this;
    74    }//init
    75
    76    protected void initLocalData() {
    77      runAction = new RunAction();
    78    }//initLocalData
    79
    80    protected void initGuiComponents() {
    81      setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    82
    83
    84      JPanel topBox = new JPanel();
    85      topBox.setLayout(new BoxLayout(topBox, BoxLayout.X_AXIS));
    86      topBox.setAlignmentX(Component.LEFT_ALIGNMENT);
    87
    88      loadedPRsTableModel = new LoadedPRsTableModel();
    89      loadedPRsTable = new XJTable();
    90      loadedPRsTable.setModel(loadedPRsTableModel);
    91
    92      loadedPRsTable.setDefaultRenderer(ProcessingResource.class,
    93                                        new ResourceRenderer());
    94
    95      loadedPRsTable.setIntercellSpacing(new Dimension(5, 5));
    96      final int width1 = new JLabel("Loaded Processing resources").
    97                  getPreferredSize().width + 10;
    98      JScrollPane scroller = new JScrollPane(){
    99        public Dimension getPreferredSize(){
    100         Dimension dim = super.getPreferredSize();
    101         dim.width = Math.max(dim.width, width1);
    102         return dim;
    103       }
    104     };
    105     scroller.getViewport().setView(loadedPRsTable);
    106     scroller.setBorder(BorderFactory.
    107                        createTitledBorder(BorderFactory.createEtchedBorder(),
    108                                           "Loaded Processing resources"));
    109
    110     topBox.add(scroller);
    111     topBox.add(Box.createHorizontalGlue());
    112
    113     addButon = new JButton(MainFrame.getIcon("right.gif"));
    114     removeButton = new JButton(MainFrame.getIcon("left.gif"));
    115
    116     Box buttonsBox =Box.createVerticalBox();
    117     buttonsBox.add(Box.createVerticalGlue());
    118     buttonsBox.add(addButon);
    119     buttonsBox.add(Box.createVerticalStrut(5));
    120     buttonsBox.add(removeButton);
    121     buttonsBox.add(Box.createVerticalGlue());
    122
    123     topBox.add(buttonsBox);
    124     topBox.add(Box.createHorizontalGlue());
    125
    126     memberPRsTableModel = new MemberPRsTableModel();
    127     memberPRsTable = new XJTable(memberPRsTableModel);
    128     memberPRsTable.setSortable(false);
    129     memberPRsTable.setDefaultRenderer(ProcessingResource.class,
    130                                       new ResourceRenderer());
    131     memberPRsTable.setIntercellSpacing(new Dimension(5, 5));
    132
    133     final int width2 = new JLabel("Selected Processing resources").
    134                            getPreferredSize().width + 10;
    135     scroller = new JScrollPane(){
    136       public Dimension getPreferredSize(){
    137         Dimension dim = super.getPreferredSize();
    138         dim.width = Math.max(dim.width, width2);
    139         return dim;
    140       }
    141     };
    142     scroller.getViewport().setView(memberPRsTable);
    143     scroller.setBorder(BorderFactory.
    144                        createTitledBorder(BorderFactory.createEtchedBorder(),
    145                                           "Selected Processing resources"));
    146
    147
    148     topBox.add(scroller);
    149
    150     moveUpButton = new JButton(MainFrame.getIcon("moveup.gif"));
    151     moveDownButton = new JButton(MainFrame.getIcon("movedown.gif"));
    152
    153     buttonsBox =Box.createVerticalBox();
    154     buttonsBox.add(Box.createVerticalGlue());
    155     buttonsBox.add(moveUpButton);
    156     buttonsBox.add(Box.createVerticalStrut(5));
    157     buttonsBox.add(moveDownButton);
    158     buttonsBox.add(Box.createVerticalGlue());
    159
    160     topBox.add(buttonsBox);
    161     topBox.add(Box.createHorizontalGlue());
    162
    163     add(topBox);
    164
    165     if(analyserMode){
    166       //we need to add the corpus combo
    167       corpusCombo = new JComboBox(corpusComboModel = new CorporaComboModel());
    168       corpusCombo.setRenderer(new ResourceRenderer());
    169       if(((SerialAnalyserController)controller).getCorpus() != null){
    170         corpusCombo.setSelectedItem(((SerialAnalyserController)controller).
    171                                      getCorpus());
    172       }else{
    173         if(corpusCombo.getModel().getSize() > 1) corpusCombo.setSelectedIndex(1);
    174         else corpusCombo.setSelectedIndex(0);
    175       }
    176       JPanel horBox = new JPanel();
    177       horBox.setLayout(new BoxLayout(horBox, BoxLayout.X_AXIS));
    178       horBox.setAlignmentX(Component.LEFT_ALIGNMENT);
    179       horBox.add(new JLabel("Corpus:"));
    180       horBox.add(Box.createHorizontalStrut(5));
    181       horBox.add(corpusCombo);
    182       horBox.add(Box.createHorizontalGlue());
    183       add(horBox);
    184       JLabel warningLbl = new JLabel(
    185         "<HTML>The <b>corpus</b> and <b>document</b> parameters are not " +
    186         "available as they are automatically set by the controller!</HTML>");
    187       warningLbl.setAlignmentX(java.awt.Component.LEFT_ALIGNMENT);
    188       add(warningLbl);
    189     }
    190
    191     parametersPanel = new JPanel();
    192     parametersPanel.setLayout(new BoxLayout(parametersPanel, BoxLayout.Y_AXIS));
    193     parametersPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    194     parametersBorder = BorderFactory.createTitledBorder(
    195                                       BorderFactory.createEtchedBorder(),
    196                                       "No selected processing resource");
    197     parametersPanel.setBorder(parametersBorder);
    198     parametersEditor = new ResourceParametersEditor();
    199     parametersEditor.init(null, null);
    200     parametersPanel.add(new JScrollPane(parametersEditor));
    201     add(Box.createVerticalStrut(5));
    202     add(parametersPanel);
    203
    204
    205     add(Box.createVerticalStrut(5));
    206     add(Box.createVerticalGlue());
    207     JPanel horBox = new JPanel();
    208     horBox.setLayout(new BoxLayout(horBox, BoxLayout.X_AXIS));
    209     horBox.setAlignmentX(Component.LEFT_ALIGNMENT);
    210     horBox.add(Box.createHorizontalGlue());
    211     horBox.add(new JButton(runAction));
    212     horBox.add(Box.createHorizontalStrut(10));
    213     add(horBox);
    214     add(Box.createVerticalStrut(10));
    215
    216     addMenu = new JMenu("Add");
    217     removeMenu = new JMenu("Remove");
    218   }// initGuiComponents()
    219
    220   protected void initListeners() {
    221     Gate.getCreoleRegister().addCreoleListener(this);
    222
    223     this.addMouseListener(new MouseAdapter() {
    224       public void mouseClicked(MouseEvent e) {
    225         if(SwingUtilities.isRightMouseButton(e)){
    226           if(handle != null && handle.getPopup()!= null)
    227             handle.getPopup().show(SerialControllerEditor.this, e.getX(), e.getY());
    228         }
    229       }
    230     });
    231
    232     addButon.addActionListener(new ActionListener() {
    233       public void actionPerformed(ActionEvent e) {
    234         int rows[] = loadedPRsTable.getSelectedRows();
    235         if(rows == null || rows.length == 0){
    236           JOptionPane.showMessageDialog(
    237               SerialControllerEditor.this,
    238               "Please select some components from the list of available components!\n" ,
    239               "Gate", JOptionPane.ERROR_MESSAGE);
    240         } else {
    241           List actions = new ArrayList();
    242           for(int i = 0; i < rows.length; i++) {
    243             Action act =(Action)new AddPRAction((ProcessingResource)
    244                                      loadedPRsTable.getValueAt(rows[i], 0));
    245             if(act != null) actions.add(act);
    246           }
    247           Iterator actIter = actions.iterator();
    248           while(actIter.hasNext()){
    249             ((Action)actIter.next()).actionPerformed(null);
    250           }
    251         }
    252       }
    253     });
    254
    255     removeButton.addActionListener(new ActionListener() {
    256       public void actionPerformed(ActionEvent e) {
    257         int rows[] = memberPRsTable.getSelectedRows();
    258         if(rows == null || rows.length == 0){
    259           JOptionPane.showMessageDialog(
    260               SerialControllerEditor.this,
    261               "Please select some components to be removed "+
    262               "from the list of used components!\n" ,
    263               "Gate", JOptionPane.ERROR_MESSAGE);
    264         } else {
    265           List actions = new ArrayList();
    266           for(int i = 0; i < rows.length; i++){
    267             Action act =(Action)new RemovePRAction((ProcessingResource)
    268                                      memberPRsTable.getValueAt(rows[i], 0));
    269             if(act != null) actions.add(act);
    270           }
    271           Iterator actIter = actions.iterator();
    272           while(actIter.hasNext()){
    273             ((Action)actIter.next()).actionPerformed(null);
    274           }
    275         }// else
    276       }//  public void actionPerformed(ActionEvent e)
    277     });
    278
    279     moveUpButton.addActionListener(new ActionListener() {
    280       public void actionPerformed(ActionEvent e) {
    281         int rows[] = memberPRsTable.getSelectedRows();
    282         if(rows == null || rows.length == 0){
    283           JOptionPane.showMessageDialog(
    284               SerialControllerEditor.this,
    285               "Please select some components to be moved "+
    286               "from the list of used components!\n" ,
    287               "Gate", JOptionPane.ERROR_MESSAGE);
    288         } else {
    289           //we need to make sure the rows are sorted
    290           Arrays.sort(rows);
    291           //get the list of PRs
    292           for(int i = 0; i < rows.length; i++){
    293             int row = rows[i];
    294             if(row > 0){
    295               //move it up
    296               ProcessingResource value = controller.remove(row);
    297               controller.add(row - 1, value);
    298             }
    299           }
    300           memberPRsTableModel.fireTableDataChanged();
    301           //restore selection
    302           for(int i = 0; i < rows.length; i++){
    303             int newRow = -1;
    304             if(rows[i] > 0) newRow = rows[i] - 1;
    305             else newRow = rows[i];
    306             memberPRsTable.addRowSelectionInterval(newRow, newRow);
    307           }
    308         }
    309
    310       }//public void actionPerformed(ActionEvent e)
    311     });
    312
    313
    314     moveDownButton.addActionListener(new ActionListener() {
    315       public void actionPerformed(ActionEvent e) {
    316         int rows[] = memberPRsTable.getSelectedRows();
    317         if(rows == null || rows.length == 0){
    318           JOptionPane.showMessageDialog(
    319               SerialControllerEditor.this,
    320               "Please select some components to be moved "+
    321               "from the list of used components!\n" ,
    322               "Gate", JOptionPane.ERROR_MESSAGE);
    323         } else {
    324           //we need to make sure the rows are sorted
    325           Arrays.sort(rows);
    326           //get the list of PRs
    327           for(int i = rows.length - 1; i >= 0; i--){
    328             int row = rows[i];
    329             if(row < controller.getPRs().size() -1){
    330               //move it down
    331               ProcessingResource value = controller.remove(row);
    332               controller.add(row + 1, value);
    333             }
    334           }
    335           memberPRsTableModel.fireTableDataChanged();
    336           //restore selection
    337           for(int i = 0; i < rows.length; i++){
    338             int newRow = -1;
    339             if(rows[i] < controller.getPRs().size() - 1) newRow = rows[i] + 1;
    340             else newRow = rows[i];
    341             memberPRsTable.addRowSelectionInterval(newRow, newRow);
    342           }
    343         }
    344
    345       }//public void actionPerformed(ActionEvent e)
    346     });
    347
    348     loadedPRsTable.addMouseListener(new MouseAdapter() {
    349       public void mouseClicked(MouseEvent e) {
    350         int row = loadedPRsTable.rowAtPoint(e.getPoint());
    351         //load modules on double click
    352         ProcessingResource pr = (ProcessingResource)
    353                                 loadedPRsTableModel.getValueAt(row, 0);
    354         if(SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2){
    355           new AddPRAction(pr).actionPerformed(null);
    356         }else if(SwingUtilities.isRightMouseButton(e)){
    357             JPopupMenu popup = new JPopupMenu();
    358             popup.add(new AddPRAction(pr){
    359               {
    360                 putValue(NAME, "Add \"" + this.pr.getName() +
    361                                "\" to the \"" + controller.getName() +
    362                                "\" application");
    363               }
    364             });
    365             popup.show(loadedPRsTable, e.getPoint().x, e.getPoint().y);
    366           }
    367       }
    368
    369       public void mousePressed(MouseEvent e) {
    370       }
    371
    372       public void mouseReleased(MouseEvent e) {
    373       }
    374
    375       public void mouseEntered(MouseEvent e) {
    376       }
    377
    378       public void mouseExited(MouseEvent e) {
    379       }
    380     });
    381
    382     memberPRsTable.addMouseListener(new MouseAdapter() {
    383       public void mouseClicked(MouseEvent e) {
    384         final int row = memberPRsTable.rowAtPoint(e.getPoint());
    385         if(row != -1){
    386           //edit parameters on double click
    387           if(SwingUtilities.isLeftMouseButton(e) /*&& e.getClickCount() == 2*/){
    388             ProcessingResource pr = (ProcessingResource)
    389                                     memberPRsTableModel.getValueAt(row, 0);
    390             showParamsEditor(pr);
    391           }else if(SwingUtilities.isRightMouseButton(e)){
    392             JPopupMenu popup = new JPopupMenu();
    393             popup.add(new AbstractAction("Edit parameters"){
    394               public void actionPerformed(ActionEvent e){
    395                 ProcessingResource pr = (ProcessingResource)
    396                                         memberPRsTableModel.getValueAt(row, 0);
    397                 showParamsEditor(pr);
    398               }
    399             });
    400             popup.show(memberPRsTable, e.getPoint().x, e.getPoint().y);
    401           }
    402         }
    403       }
    404
    405       public void mousePressed(MouseEvent e) {
    406       }
    407
    408       public void mouseReleased(MouseEvent e) {
    409       }
    410
    411       public void mouseEntered(MouseEvent e) {
    412       }
    413
    414       public void mouseExited(MouseEvent e) {
    415       }
    416     });
    417
    418     addMenu.addMenuListener(new MenuListener() {
    419       public void menuCanceled(MenuEvent e) {
    420
    421       }
    422
    423       public void menuDeselected(MenuEvent e) {
    424       }
    425
    426       public void menuSelected(MenuEvent e) {
    427         addMenu.removeAll();
    428         Iterator prIter = Gate.getCreoleRegister().getPrInstances().iterator();
    429         while(prIter.hasNext()){
    430           ProcessingResource pr = (ProcessingResource)prIter.next();
    431           if(Gate.getHiddenAttribute(pr.getFeatures())){
    432             //ignore this resource
    433           }else{
    434             addMenu.add(new AddPRAction(pr));
    435           }
    436         }// while
    437       }
    438     });
    439
    440     removeMenu.addMenuListener(new MenuListener() {
    441       public void menuCanceled(MenuEvent e) {
    442       }
    443
    444       public void menuDeselected(MenuEvent e) {
    445       }
    446
    447       public void menuSelected(MenuEvent e) {
    448         removeMenu.removeAll();
    449         Iterator prIter = Gate.getCreoleRegister().getPrInstances().iterator();
    450         while(prIter.hasNext()){
    451           ProcessingResource pr = (ProcessingResource)prIter.next();
    452           if(Gate.getHiddenAttribute(pr.getFeatures())){
    453             //ignore this resource
    454           }else{
    455             removeMenu.add(new RemovePRAction(pr));
    456           }
    457         }// while
    458       }
    459     });
    460   }//protected void initListeners()
    461
    462   /**
    463    * Stops the current edits for parameters; sets the paarmeters for the
    464    * resource currently being edited and diplays the editor for the new
    465    * resource
    466    * @param pr the new resource
    467    */
    468   protected void showParamsEditor(ProcessingResource pr){
    469     try{
    470       if(parametersEditor.getResource() != null) parametersEditor.setParameters();
    471     }catch(ResourceInstantiationException rie){
    472       JOptionPane.showMessageDialog(
    473           SerialControllerEditor.this,
    474           "Failed to set parameters for \"" + pr.getName() +"\"!\n" ,
    475           "Gate", JOptionPane.ERROR_MESSAGE);
    476       rie.printStackTrace(Err.getPrintWriter());
    477     }
    478
    479     if(pr != null){
    480       ResourceData rData = (ResourceData)Gate.getCreoleRegister().
    481                                          get(pr.getClass().getName());
    482
    483       parametersBorder.setTitle("Parameters for the \"" + pr.getName() +
    484                                 "\" " + rData.getName());
    485
    486       //this is a list of lists
    487       List parameters = rData.getParameterList().getRuntimeParameters();
    488
    489       if(analyserMode){
    490         //remove corpus and document
    491         //create a new list so we don't change the one from CreoleReg.
    492         List newParameters = new ArrayList();
    493         Iterator pDisjIter = parameters.iterator();
    494         while(pDisjIter.hasNext()){
    495           List aDisjunction = (List)pDisjIter.next();
    496           List newDisjunction = new ArrayList(aDisjunction);
    497           Iterator internalParIter = newDisjunction.iterator();
    498           while(internalParIter.hasNext()){
    499             Parameter parameter = (Parameter)internalParIter.next();
    500             if(parameter.getName().equals("corpus") ||
    501                parameter.getName().equals("document")) internalParIter.remove();
    502           }
    503           if(!newDisjunction.isEmpty()) newParameters.add(newDisjunction);
    504         }
    505         parametersEditor.init(pr, newParameters);
    506       }else{
    507         parametersEditor.init(pr, parameters);
    508       }
    509     }else{
    510       parametersBorder.setTitle("No selected processing resource");
    511       parametersEditor.init(null, null);
    512     }
    513     SerialControllerEditor.this.validate();
    514     SerialControllerEditor.this.repaint(100);
    515   }
    516
    517   //CreoleListener implementation
    518   public void resourceLoaded(CreoleEvent e) {
    519     if(Gate.getHiddenAttribute(e.getResource().getFeatures())) return;
    520     if(e.getResource() instanceof ProcessingResource){
    521       loadedPRsTableModel.fireTableDataChanged();
    522       memberPRsTableModel.fireTableDataChanged();
    523       repaint(100);
    524     }else if(e.getResource() instanceof LanguageResource){
    525       if(e.getResource() instanceof Corpus && analyserMode){
    526         corpusComboModel.fireDataChanged();
    527       }
    528     }
    529   }// public void resourceLoaded
    530
    531   public void resourceUnloaded(CreoleEvent e) {
    532     if(Gate.getHiddenAttribute(e.getResource().getFeatures())) return;
    533     if(e.getResource() instanceof ProcessingResource){
    534       ProcessingResource pr = (ProcessingResource)e.getResource();
    535       if(controller.getPRs().contains(pr)){
    536         new RemovePRAction(pr).actionPerformed(null);
    537       }
    538       loadedPRsTableModel.fireTableDataChanged();
    539       memberPRsTableModel.fireTableDataChanged();
    540       repaint(100);
    541     }
    542   }//public void resourceUnloaded(CreoleEvent e)
    543
    544   public void datastoreOpened(CreoleEvent e) {
    545   }
    546   public void datastoreCreated(CreoleEvent e) {
    547   }
    548   public void datastoreClosed(CreoleEvent e) {
    549   }
    550   public synchronized void removeStatusListener(StatusListener l) {
    551     if (statusListeners != null && statusListeners.contains(l)) {
    552       Vector v = (Vector) statusListeners.clone();
    553       v.removeElement(l);
    554       statusListeners = v;
    555     }
    556   }
    557   public synchronized void addStatusListener(StatusListener l) {
    558     Vector v = statusListeners == null ? new Vector(2) :
    559                                   (Vector) statusListeners.clone();
    560     if (!v.contains(l)) {
    561       v.addElement(l);
    562       statusListeners = v;
    563     }
    564   }
    565
    566
    567
    568   /**
    569    * Table model for all the loaded processing resources that are not part of
    570    * the controller.
    571    */
    572   class LoadedPRsTableModel extends AbstractTableModel{
    573     public int getRowCount(){
    574       List loadedPRs = new ArrayList(Gate.getCreoleRegister().getPrInstances());
    575       loadedPRs.removeAll(controller.getPRs());
    576       Iterator prsIter = loadedPRs.iterator();
    577       while(prsIter.hasNext()){
    578         ProcessingResource aPR = (ProcessingResource)prsIter.next();
    579         if(Gate.getHiddenAttribute(aPR.getFeatures())) prsIter.remove();
    580       }
    581
    582       return loadedPRs.size();
    583     }
    584
    585     public Object getValueAt(int row, int column){
    586       List loadedPRs = new ArrayList(Gate.getCreoleRegister().getPrInstances());
    587       loadedPRs.removeAll(controller.getPRs());
    588       Iterator prsIter = loadedPRs.iterator();
    589       while(prsIter.hasNext()){
    590         ProcessingResource aPR = (ProcessingResource)prsIter.next();
    591         if(Gate.getHiddenAttribute(aPR.getFeatures())) prsIter.remove();
    592       }
    593
    594       Collections.sort(loadedPRs, nameComparator);
    595       ProcessingResource pr = (ProcessingResource)loadedPRs.get(row);
    596       switch(column){
    597         case 0 : return pr;
    598         case 1 : {
    599           ResourceData rData = (ResourceData)Gate.getCreoleRegister().
    600                                     get(pr.getClass().getName());
    601           if(rData == null) return pr.getClass();
    602           else return rData.getName();
    603         }
    604         default: return null;
    605       }
    606     }
    607
    608     public int getColumnCount(){
    609       return 2;
    610     }
    611
    612     public String getColumnName(int columnIndex){
    613       switch(columnIndex){
    614         case 0 : return "Name";
    615         case 1 : return "Type";
    616         default: return "?";
    617       }
    618     }
    619
    620     public Class getColumnClass(int columnIndex){
    621       switch(columnIndex){
    622         case 0 : return ProcessingResource.class;
    623         case 1 : return String.class;
    624         default: return Object.class;
    625       }
    626     }
    627
    628     public boolean isCellEditable(int rowIndex, int columnIndex){
    629       return false;
    630     }
    631
    632     public void setValueAt(Object aValue, int rowIndex, int columnIndex){
    633     }
    634     NameComparator nameComparator = new NameComparator();
    635   }//protected class LoadedPRsTableModel extends AbstractTableModel
    636
    637   /**
    638    * A model for a combobox containing the loaded corpora in the system
    639    */
    640   protected class CorporaComboModel extends AbstractListModel
    641                                   implements ComboBoxModel{
    642     public int getSize(){
    643       //get all corpora regardless of their actual type
    644       java.util.List loadedCorpora = null;
    645       try{
    646         loadedCorpora = Gate.getCreoleRegister().
    647                                getAllInstances("gate.Corpus");
    648       }catch(GateException ge){
    649         ge.printStackTrace(Err.getPrintWriter());
    650       }
    651
    652       return loadedCorpora == null ? 1 : loadedCorpora.size() + 1;
    653     }
    654
    655     public Object getElementAt(int index){
    656       if(index == 0) return "<none>";
    657       else{
    658         //get all corpora regardless of their actual type
    659         java.util.List loadedCorpora = null;
    660         try{
    661           loadedCorpora = Gate.getCreoleRegister().
    662                                  getAllInstances("gate.Corpus");
    663         }catch(GateException ge){
    664           ge.printStackTrace(Err.getPrintWriter());
    665         }
    666         return loadedCorpora == null? "" : loadedCorpora.get(index - 1);
    667       }
    668     }
    669
    670     //use the controller for data caching
    671     public void setSelectedItem(Object anItem){
    672       ((SerialAnalyserController)controller).
    673         setCorpus((Corpus)(anItem.equals("<none>") ? null : anItem));
    674     }
    675
    676     public Object getSelectedItem(){
    677       Corpus corpus = ((SerialAnalyserController)controller).getCorpus();
    678       return (corpus == null ? (Object)"<none>" : (Object)corpus);
    679     }
    680
    681     void fireDataChanged(){
    682       fireContentsChanged(this, 0, getSize());
    683     }
    684
    685     Object selectedItem = null;
    686   }
    687
    688   /**
    689    * Table model for all the processing resources in the controller.
    690    */
    691   class MemberPRsTableModel extends AbstractTableModel{
    692     public int getRowCount(){
    693       return controller.getPRs().size();
    694     }
    695
    696     public Object getValueAt(int row, int column){
    697       ProcessingResource pr = (ProcessingResource)
    698                               ((List)controller.getPRs()).get(row);
    699       switch(column){
    700         case 0 : return pr;
    701 //        case 1 : return new Boolean(checkRuntimeParameters(pr));
    702         case 1 : {
    703           ResourceData rData = (ResourceData)Gate.getCreoleRegister().
    704                                     get(pr.getClass().getName());
    705           if(rData == null) return pr.getClass();
    706           else return rData.getName();
    707         }
    708         default: return null;
    709       }
    710     }
    711
    712     public int getColumnCount(){
    713       return 2;
    714     }
    715
    716     public String getColumnName(int columnIndex){
    717       switch(columnIndex){
    718         case 0 : return "Name";
    719 //        case 1 : return "!";
    720         case 1 : return "Type";
    721         default: return "?";
    722       }
    723     }
    724
    725     public Class getColumnClass(int columnIndex){
    726       switch(columnIndex){
    727         case 0 : return ProcessingResource.class;
    728 //        case 1 : return Boolean.class;
    729         case 1 : return String.class;
    730         default: return Object.class;
    731       }
    732     }
    733
    734     public boolean isCellEditable(int rowIndex, int columnIndex){
    735       return false;
    736     }
    737
    738     public void setValueAt(Object aValue, int rowIndex, int columnIndex){
    739     }
    740   }//protected class MemeberPRsTableModel extends AbstractTableModel
    741
    742   /** Adds a PR to the controller*/
    743   class AddPRAction extends AbstractAction {
    744     AddPRAction(ProcessingResource aPR){
    745       super(aPR.getName());
    746       this.pr = aPR;
    747       setEnabled(!controller.getPRs().contains(aPR));
    748     }
    749
    750     public void actionPerformed(ActionEvent e){
    751       controller.add(pr);
    752       loadedPRsTableModel.fireTableDataChanged();
    753       memberPRsTableModel.fireTableDataChanged();
    754       SerialControllerEditor.this.validate();
    755       SerialControllerEditor.this.repaint(100);
    756     }
    757
    758     ProcessingResource pr;
    759   }
    760
    761   /** Removes a PR from the controller*/
    762   class RemovePRAction extends AbstractAction {
    763     RemovePRAction(ProcessingResource pr){
    764       super(pr.getName());
    765       this.pr = pr;
    766       setEnabled(controller.getPRs().contains(pr));
    767     }
    768
    769     public void actionPerformed(ActionEvent e){
    770       if(controller.remove(pr)){
    771         loadedPRsTableModel.fireTableDataChanged();
    772         memberPRsTableModel.fireTableDataChanged();
    773         if(parametersEditor.getResource() == pr){
    774           parametersEditor.init(null, null);
    775           parametersBorder.setTitle("No selected processing resource");
    776         }
    777         SerialControllerEditor.this.validate();
    778         SerialControllerEditor.this.repaint(100);
    779       }
    780     }
    781
    782     ProcessingResource pr;
    783   }
    784
    785
    786   /** Runs the Application*/
    787   class RunAction extends AbstractAction {
    788     RunAction(){
    789       super("Run");
    790     }
    791
    792     public void actionPerformed(ActionEvent e){
    793       Runnable runnable = new Runnable(){
    794         public void run(){
    795
    796           //stop editing the parameters
    797           try{
    798             parametersEditor.setParameters();
    799           }catch(ResourceInstantiationException rie){
    800             JOptionPane.showMessageDialog(
    801               SerialControllerEditor.this,
    802               "Could not set parameters for the \"" +
    803               parametersEditor.getResource().getName() +
    804               "\" processing resource:\nSee \"Messages\" tab for details!",
    805               "Gate", JOptionPane.ERROR_MESSAGE);
    806               rie.printStackTrace(Err.getPrintWriter());
    807               return;
    808           }
    809
    810           if(analyserMode){
    811             //set the corpus
    812             Object value = corpusCombo.getSelectedItem();
    813             Corpus corpus = value.equals("<none>") ? null : (Corpus)value;
    814             if(corpus == null){
    815               JOptionPane.showMessageDialog(
    816                 SerialControllerEditor.this,
    817                 "No corpus provided!\n" +
    818                 "Please select a corpus and try again!",
    819                 "Gate", JOptionPane.ERROR_MESSAGE);
    820               return;
    821             }
    822             ((SerialAnalyserController)controller).setCorpus(corpus);
    823           }
    824           //check the runtime parameters
    825           List badPRs;
    826           try{
    827             badPRs = controller.getOffendingPocessingResources();
    828           }catch(ResourceInstantiationException rie){
    829             JOptionPane.showMessageDialog(
    830               SerialControllerEditor.this,
    831               "Could not check runtime parameters for " +
    832               "the processing resources:\n" + rie.toString(),
    833               "Gate", JOptionPane.ERROR_MESSAGE);
    834             return;
    835           }
    836           if(badPRs != null && !badPRs.isEmpty()){
    837             //we know what PRs have problems so it would be nice to show
    838             //them in red or something
    839             JOptionPane.showMessageDialog(
    840               SerialControllerEditor.this,
    841               "Some required runtime parameters are not set!",
    842               "Gate", JOptionPane.ERROR_MESSAGE);
    843             return;
    844           }
    845
    846           //set the listeners
    847           StatusListener sListener = new InternalStatusListener();
    848           ProgressListener pListener = new InternalProgressListener();
    849
    850           controller.addStatusListener(sListener);
    851           controller.addProgressListener(pListener);
    852
    853           Gate.setExecutable(controller);
    854
    855           //execute the thing
    856           long startTime = System.currentTimeMillis();
    857           fireStatusChanged("Running " +
    858                             controller.getName());
    859           fireProgressChanged(0);
    860
    861           try {
    862             controller.execute();
    863           }catch(ExecutionInterruptedException eie){
    864             JOptionPane.showMessageDialog(
    865               SerialControllerEditor.this,
    866               "Interrupted!\n" + eie.toString(),
    867               "Gate", JOptionPane.ERROR_MESSAGE);
    868           }catch(ExecutionException ee) {
    869             ee.printStackTrace(Err.getPrintWriter());
    870             JOptionPane.showMessageDialog(
    871               SerialControllerEditor.this,
    872               "Execution error while running \"" + controller.getName() +
    873               "\" :\nSee \"Messages\" tab for details!",
    874               "Gate", JOptionPane.ERROR_MESSAGE);
    875           }catch(Exception e){
    876             JOptionPane.showMessageDialog(SerialControllerEditor.this,
    877                                           "Unhandled execution error!\n " +
    878                                           "See \"Messages\" tab for details!",
    879                                           "Gate", JOptionPane.ERROR_MESSAGE);
    880             e.printStackTrace(Err.getPrintWriter());
    881           }finally{
    882             Gate.setExecutable(null);
    883           }//catch
    884
    885           //remove the listeners
    886           controller.removeStatusListener(sListener);
    887           controller.removeProgressListener(pListener);
    888
    889           long endTime = System.currentTimeMillis();
    890           fireProcessFinished();
    891           fireStatusChanged(controller.getName() +
    892                             " run in " +
    893                             NumberFormat.getInstance().format(
    894                             (double)(endTime - startTime) / 1000) + " seconds");
    895         }
    896       };
    897       Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
    898                                  runnable,
    899                                  "ApplicationViewer1");
    900       thread.setPriority(Thread.MIN_PRIORITY);
    901       thread.start();
    902     }//public void actionPerformed(ActionEvent e)
    903   }//class RunAction
    904
    905   /**
    906    * A simple progress listener used to forward the events upstream.
    907    */
    908   protected class InternalProgressListener implements ProgressListener{
    909     public void progressChanged(int i){
    910       fireProgressChanged(i);
    911     }
    912
    913     public void processFinished(){
    914       fireProcessFinished();
    915     }
    916   }//InternalProgressListener
    917
    918   /**
    919    * A simple status listener used to forward the events upstream.
    920    */
    921   protected class InternalStatusListener implements StatusListener{
    922     public void statusChanged(String message){
    923       fireStatusChanged(message);
    924     }
    925   }//InternalStatusListener
    926
    927   /** The controller this editor edits */
    928   SerialController controller;
    929
    930   /** The {@link Handle} that created this view */
    931   Handle handle;
    932
    933   /**
    934    * Contains all the PRs loaded in the sytem that are not already part of the
    935    * serial controller
    936    */
    937   XJTable loadedPRsTable;
    938
    939   /**
    940    * model for the {@link loadedPRsTable} JTable.
    941    */
    942   LoadedPRsTableModel loadedPRsTableModel;
    943
    944   /**
    945    * Displays the PRs in the controller
    946    */
    947   XJTable memberPRsTable;
    948
    949   /** model for {@link memberPRsTable}*/
    950   MemberPRsTableModel memberPRsTableModel;
    951
    952   /** Adds one or more PR(s) to the controller*/
    953   JButton addButon;
    954
    955   /** Removes one or more PR(s) from the controller*/
    956   JButton removeButton;
    957
    958   /** Moves the module up in the controller list*/
    959   JButton moveUpButton;
    960
    961   /** Moves the module down in the controller list*/
    962   JButton moveDownButton;
    963
    964   /** A component for editing the parameters of the currently selected PR*/
    965   ResourceParametersEditor parametersEditor;
    966
    967   /** A JPanel containing the {@link parametersEditor}*/
    968   JPanel parametersPanel;
    969
    970   /** A border for the {@link parametersPanel} */
    971   TitledBorder parametersBorder;
    972
    973   /**
    974    * A combobox that allows selection of a corpus from the list of loaded
    975    * corpora.
    976    */
    977   JComboBox corpusCombo;
    978
    979   CorporaComboModel corpusComboModel;
    980
    981   /**The "Add PR" menu; part of the popup menu*/
    982   JMenu addMenu;
    983
    984   /**The "Remove PR" menu; part of the popup menu*/
    985   JMenu removeMenu;
    986
    987   /** Action that runs the application*/
    988   RunAction runAction;
    989
    990   boolean analyserMode = false;
    991
    992   private transient Vector statusListeners;
    993   private transient Vector progressListeners;
    994
    995
    996
    997   protected void fireStatusChanged(String e) {
    998     if (statusListeners != null) {
    999       Vector listeners = statusListeners;
    1000      int count = listeners.size();
    1001      for (int i = 0; i < count; i++) {
    1002        ((StatusListener) listeners.elementAt(i)).statusChanged(e);
    1003      }
    1004    }
    1005  }
    1006  public synchronized void removeProgressListener(ProgressListener l) {
    1007    if (progressListeners != null && progressListeners.contains(l)) {
    1008      Vector v = (Vector) progressListeners.clone();
    1009      v.removeElement(l);
    1010      progressListeners = v;
    1011    }
    1012  }
    1013  public synchronized void addProgressListener(ProgressListener l) {
    1014    Vector v = progressListeners == null ? new Vector(2) : (Vector) progressListeners.clone();
    1015    if (!v.contains(l)) {
    1016      v.addElement(l);
    1017      progressListeners = v;
    1018    }
    1019  }
    1020  protected void fireProgressChanged(int e) {
    1021    if (progressListeners != null) {
    1022      Vector listeners = progressListeners;
    1023      int count = listeners.size();
    1024      for (int i = 0; i < count; i++) {
    1025        ((ProgressListener) listeners.elementAt(i)).progressChanged(e);
    1026      }
    1027    }
    1028  }
    1029  protected void fireProcessFinished() {
    1030    if (progressListeners != null) {
    1031      Vector listeners = progressListeners;
    1032      int count = listeners.size();
    1033      for (int i = 0; i < count; i++) {
    1034        ((ProgressListener) listeners.elementAt(i)).processFinished();
    1035      }
    1036    }
    1037  }
    1038  }//SerialControllerEditor
    1039

| SerialControllerEditor |