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 03/10/2001
10   *
11   *  $Id: ResourceParametersEditor.java,v 1.34 2003/05/13 14:09:18 valyt Exp $
12   *
13   */
14  
15  package gate.gui;
16  
17  import java.awt.Frame;
18  import java.awt.BorderLayout;
19  import java.awt.Component;
20  import java.awt.Dimension;
21  import java.awt.Insets;
22  import java.awt.Graphics;
23  import java.awt.Window;
24  import java.awt.event.*;
25  import javax.swing.*;
26  import javax.swing.table.*;
27  import javax.swing.tree.*;
28  import javax.swing.event.*;
29  import javax.swing.border.*;
30  
31  import java.util.*;
32  import java.net.URL;
33  import java.io.IOException;
34  import java.text.*;
35  
36  import gate.*;
37  import gate.util.*;
38  import gate.swing.*;
39  import gate.creole.*;
40  import gate.event.*;
41  
42  /**
43   * Allows the editing of a set of parameters for a resource. It needs a pointer
44   * to the resource and a list of the parameter names for the parameters that
45   * should be displayed. The list of the parameters is actually a list of lists
46   * of strings representing parameter disjunctions.
47   */
48  public class ResourceParametersEditor extends XJTable implements CreoleListener{
49  
50    public ResourceParametersEditor(){
51      initLocalData();
52      initGuiComponents();
53      initListeners();
54    }
55  
56    /**
57     * Initialises this GUI component.
58     * @param resource the resource for which the parameters need to be set.
59     * @param paramaters a list of lists of {@link Parameter} representing
60     * parameter disjunctions.
61     */
62    public void init(Resource resource, List parameters){
63      cleanup();
64      this.resource = resource;
65      if(parameters != null){
66        parameterDisjunctions = new ArrayList(parameters.size());
67        for(int i = 0; i < parameters.size(); i++){
68          parameterDisjunctions.add(
69                              new ParameterDisjunction(resource,
70                                                       (List)parameters.get(i)));
71        }
72      }else{
73        parameterDisjunctions = null;
74      }
75      tableModel.fireTableDataChanged();
76      adjustSizes();
77    }
78  
79    protected void initLocalData(){
80      resource = null;
81      parameterDisjunctions = null;
82    }// protected void initLocalData()
83  
84    protected void initGuiComponents(){
85      setModel(tableModel = new ParametersTableModel());
86  
87      getColumnModel().getColumn(0).
88                       setCellRenderer(new ParameterDisjunctionRenderer());
89  
90      getColumnModel().getColumn(1).
91                       setCellRenderer(new DefaultTableCellRenderer());
92  
93      getColumnModel().getColumn(2).
94                       setCellRenderer(new BooleanRenderer());
95  
96      getColumnModel().getColumn(3).
97                       setCellRenderer(new ParameterValueRenderer());
98  
99  
100     getColumnModel().getColumn(0).
101                      setCellEditor(new ParameterDisjunctionEditor());
102 
103     getColumnModel().getColumn(3).
104                      setCellEditor(new ParameterValueEditor());
105 
106     setIntercellSpacing(new Dimension(5, 5));
107 
108     setSurrendersFocusOnKeystroke(true);
109   }// protected void initGuiComponents()
110 
111 
112   protected void initListeners(){
113     Gate.getCreoleRegister().addCreoleListener(this);
114     addKeyListener(new KeyAdapter() {
115       public void keyTyped(KeyEvent e) {
116         if(e.getKeyCode() == e.VK_ENTER){
117           if(getEditingColumn() == -1 && getEditingRow() == -1){
118             getParent().dispatchEvent(e);
119           }
120         }
121       }
122 
123       public void keyPressed(KeyEvent e) {
124       }
125 
126       public void keyReleased(KeyEvent e) {
127       }
128     });
129   }
130 
131   /**
132    * Cleans the internal data and prepares this object to be collected
133    */
134   public void cleanup(){
135     Gate.getCreoleRegister().removeCreoleListener(this);
136     if(parameterDisjunctions != null && parameterDisjunctions.size() > 0){
137       for (int i = 0; i < parameterDisjunctions.size(); i++){
138         ((ParameterDisjunction)parameterDisjunctions.get(i)).cleanup();
139       }
140     }
141     resource = null;
142   }
143 
144 //  /**
145 //   * Disable key handling for most keys by JTable when not editing.
146 //   */
147 //  protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
148 //                                      int condition, boolean pressed) {
149 //    int keyCode = e.getKeyCode();
150 //    if(isEditing() ||
151 //       keyCode == KeyEvent.VK_UP ||
152 //       keyCode == KeyEvent.VK_DOWN ||
153 //       keyCode == KeyEvent.VK_LEFT ||
154 //       keyCode == KeyEvent.VK_RIGHT ||
155 //       keyCode == KeyEvent.VK_TAB) return super.processKeyBinding(ks, e,
156 //                                                                  condition,
157 //                                                                  pressed);
158 //    return false;
159 //  }
160 
161   /**
162    * Should this GUI comonent allow editing?
163    */
164 
165   /**
166    * Sets the parameters for the resource to their new values as resulted
167    * from the user's edits.
168    */
169   public void setParameters() throws ResourceInstantiationException{
170     if(resource == null || parameterDisjunctions == null) return;
171     //stop current edits
172     if(getEditingColumn() != -1 && getEditingRow() != -1){
173       editingStopped(new ChangeEvent(getCellEditor(getEditingRow(),
174                                                    getEditingColumn())));
175     }
176     //set the parameters
177     for(int i = 0; i < parameterDisjunctions.size(); i++){
178       ParameterDisjunction pDisj = (ParameterDisjunction)
179                                    parameterDisjunctions.get(i);
180       resource.setParameterValue(pDisj.getName(), pDisj.getValue());
181     }
182   }
183 
184   /**
185    * Does this GUI component allow editing?
186    */
187 
188   public Resource getResource() {
189     return resource;
190   }
191 
192   /**
193    * Gets the current values for the parameters.
194    * @return a {@link FeatureMap} conatining the curent values for the curently
195    * selected parameters in each disjunction.
196    */
197   public FeatureMap getParameterValues(){
198     //stop current edits
199     if(getEditingColumn() != -1 && getEditingRow() != -1){
200       editingStopped(new ChangeEvent(getCellEditor(getEditingRow(),
201                                                    getEditingColumn())));
202     }
203     //get the parameters
204     FeatureMap values = Factory.newFeatureMap();
205     if(parameterDisjunctions != null){
206       for(int i = 0; i < parameterDisjunctions.size(); i++){
207         ParameterDisjunction pDisj = (ParameterDisjunction)
208                                      parameterDisjunctions.get(i);
209         values.put(pDisj.getName(), pDisj.getValue());
210       }
211     }
212     return values;
213   }
214 
215   public void resourceLoaded(CreoleEvent e) {
216     repaint();
217   }
218   public void resourceUnloaded(CreoleEvent e) {
219     repaint();
220   }
221 
222   public void resourceRenamed(Resource resource, String oldName,
223                               String newName){
224     repaint();
225   }
226   public void datastoreOpened(CreoleEvent e) {
227   }
228   public void datastoreCreated(CreoleEvent e) {
229   }
230   public void datastoreClosed(CreoleEvent e) {
231   }
232 
233   public void setEditable(boolean editable) {
234     this.editable = editable;
235   }
236 
237   public boolean isEditable() {
238     return editable;
239   }
240 
241   /**
242    * Called by other GUI classes that use this as a subcomponent that doesn't
243    * need to update with the creole register changes.
244    */
245   void removeCreoleListenerLink(){
246     //this component is only used as a viewer now; it doesn't need to update
247     //so we don't need to listen to creole events
248     Gate.getCreoleRegister().removeCreoleListener(this);
249     if(parameterDisjunctions != null && parameterDisjunctions.size() > 0){
250       for (int i = 0; i < parameterDisjunctions.size(); i++){
251         ((ParameterDisjunction)parameterDisjunctions.get(i)).removeCreoleListenerLink();
252       }
253     }
254 
255   }
256 
257   ParametersTableModel tableModel;
258   Resource resource;
259 
260 
261 
262   /**
263    * A list of {@link ParameterDisjunction}
264    */
265   protected List parameterDisjunctions;
266   protected boolean editable = true;
267 
268   //inner classes
269   protected class ParametersTableModel extends AbstractTableModel{
270 
271     public int getColumnCount(){return 4;}
272 
273     public Class getColumnClass(int columnIndex){
274       switch(columnIndex){
275         case 0: return ParameterDisjunction.class;
276         case 1: return String.class;
277         case 2: return Boolean.class;
278         case 3: return Object.class;
279         default: return Object.class;
280       }
281     }// public Class getColumnClass(int columnIndex)
282 
283     public String getColumnName(int columnIndex){
284       switch(columnIndex){
285         case 0: return "Name";
286         case 1: return "Type";
287         case 2: return "Required";
288         case 3: return "Value";
289         default: return "?";
290       }
291     }//public String getColumnName(int columnIndex)
292 
293     public boolean isCellEditable(int rowIndex,
294                               int columnIndex) {
295       switch(columnIndex){
296         case 0: return ((ParameterDisjunction)
297                         parameterDisjunctions.get(rowIndex)).size() > 1;
298         case 1: return false;
299         case 2: return false;
300         case 3: return editable;
301         default: return false;
302       }
303     }// public boolean isCellEditable
304 
305     public int getRowCount(){
306       return (parameterDisjunctions == null) ? 0 : parameterDisjunctions.size();
307     }
308 
309     public Object getValueAt(int rowIndex,
310                          int columnIndex) {
311       ParameterDisjunction pDisj = (ParameterDisjunction)
312                                    parameterDisjunctions.get(rowIndex);
313       switch(columnIndex){
314         case 0: return pDisj;
315         case 1: return pDisj.getType();
316         case 2: return pDisj.isRequired();
317         case 3: return pDisj.getValue();
318         default: return "?";
319       }
320     }// public Object getValueAt
321 
322     public void setValueAt(Object aValue, int rowIndex, int columnIndex){
323       ParameterDisjunction pDisj = (ParameterDisjunction)
324                                    parameterDisjunctions.get(rowIndex);
325       switch(columnIndex){
326         case 0:{
327           pDisj.setSelectedIndex(((Integer)aValue).intValue());
328           break;
329         }
330         case 1:{
331           break;
332         }
333         case 2:{
334           break;
335         }
336         case 3:{
337           pDisj.setValue(aValue);
338           break;
339         }
340         default:{}
341       }
342     }// public void setValueAt
343   }///class FeaturesTableModel extends DefaultTableModel
344 
345   class ParameterDisjunctionRenderer extends DefaultTableCellRenderer {
346     public ParameterDisjunctionRenderer(){
347       combo = new JComboBox();
348       class CustomRenderer extends JLabel implements ListCellRenderer {
349         public Component getListCellRendererComponent(JList list,
350                                                       Object value,
351                                                       int index,
352                                                       boolean isSelected,
353                                                       boolean cellHasFocus){
354 
355           setText(text);
356           setIcon(MainFrame.getIcon(iconName));
357           return this;
358         }
359       };
360       combo.setRenderer(new CustomRenderer());
361     }
362 
363     public Component getTableCellRendererComponent(JTable table,
364                                                    Object value,
365                                                    boolean isSelected,
366                                                    boolean hasFocus,
367                                                    int row,
368                                                    int column) {
369       ParameterDisjunction pDisj = (ParameterDisjunction)value;
370       text = pDisj.getName();
371       String type = pDisj.getType();
372       iconName = "param.gif";
373       if(Gate.isGateType(type)){
374         ResourceData rData = (ResourceData)Gate.getCreoleRegister().get(type);
375         if(rData != null) iconName = rData.getIcon();
376       }
377       if(pDisj.size() > 1){
378         combo.setModel(new DefaultComboBoxModel(new Object[]{text}));
379         return combo;
380       }
381       //prepare the renderer
382       Component comp = super.getTableCellRendererComponent(table,
383                                                            text,
384                                                            isSelected, hasFocus,
385                                                            row, column);
386       setIcon(MainFrame.getIcon(iconName));
387       return this;
388     }// public Component getTableCellRendererComponent
389 
390     //combobox used for OR parameters
391     JComboBox combo;
392     String iconName;
393     String text;
394   }//class ParameterDisjunctionRenderer
395 
396 
397   /**
398    * A renderer that displays a File Open button next to a text field.
399    * Used for setting URLs from files.
400    */
401   class ParameterValueRenderer extends ObjectRenderer {
402     ParameterValueRenderer() {
403       fileButton = new JButton(MainFrame.getIcon("loadFile.gif"));
404       fileButton.setToolTipText("Set from file...");
405       listButton = new JButton(MainFrame.getIcon("editList.gif"));
406       listButton.setToolTipText("Edit the list");
407       textButtonBox = new JPanel();
408       textButtonBox.setLayout(new BoxLayout(textButtonBox, BoxLayout.X_AXIS));
409       textButtonBox.setOpaque(false);
410 
411       combo = new JComboBox();
412       combo.setRenderer(new ResourceRenderer());
413     }// CustomObjectRenderer()
414 
415     public Component getTableCellRendererComponent(JTable table,
416                                                    Object value,
417                                                    boolean isSelected,
418                                                    boolean hasFocus,
419                                                    int row,
420                                                    int column) {
421 
422       String type = ((ParameterDisjunction)table.getValueAt(row, 0)).getType();
423 
424       if(Gate.isGateType(type)){
425         //Gate type
426         if(ResourceParametersEditor.this.isEditable()){
427           combo.setModel(new DefaultComboBoxModel(new Object[]{value == null ?
428                                                                "<none>" :
429                                                                value }));
430           return combo;
431         }else{
432           //not editable; we'll just use the text field
433           //prepare the renderer
434           String text = value == null ? "<none>" : value.toString();
435           super.getTableCellRendererComponent(table, text, isSelected,
436                                                 hasFocus, row, column);
437           return this;
438         }
439       }else{
440         Class typeClass = null;
441         try{
442           typeClass = Class.forName(type);
443         }catch(ClassNotFoundException cnfe){
444         }
445         //non Gate type -> we'll use the text field
446         String text = (value == null) ?
447                       "                                        " +
448                       "                                        " :
449                       value.toString();
450         //prepare the renderer
451         super.getTableCellRendererComponent(table, text, isSelected,
452                                               hasFocus, row, column);
453 
454         if(type.equals("java.net.URL")){
455           if(ResourceParametersEditor.this.isEditable()){
456             textButtonBox.removeAll();
457             textButtonBox.add(this);
458             this.setMaximumSize(new Dimension(Integer.MAX_VALUE,
459                                               getPreferredSize().height));
460             textButtonBox.add(Box.createHorizontalStrut(5));
461             textButtonBox.add(fileButton);
462             return textButtonBox;
463           }else{
464             return this;
465           }
466         }else if(typeClass != null &&
467                  List.class.isAssignableFrom(typeClass)){
468           //List value
469           setText(textForList((List)value));
470           if(ResourceParametersEditor.this.isEditable()){
471           textButtonBox.removeAll();
472           textButtonBox.add(this);
473           this.setMaximumSize(new Dimension(Integer.MAX_VALUE,
474                                             getPreferredSize().height));
475           textButtonBox.add(Box.createHorizontalStrut(5));
476           textButtonBox.add(listButton);
477           return textButtonBox;
478           }else{
479             return this;
480           }
481         }else return this;
482       }
483     }// public Component getTableCellRendererComponent
484 
485     /**
486      * Gets a string representation for a list value
487      */
488     protected String textForList(List list){
489       if(list == null || list.isEmpty()) return "[]";
490       StringBuffer res = new StringBuffer("[");
491       Iterator elemIter = list.iterator();
492       while(elemIter.hasNext()){
493         Object elem = elemIter.next();
494         res.append( ((elem instanceof NameBearer) ?
495                     ((NameBearer)elem).getName() :
496                     elem.toString()) + ", ");
497       }
498       res.delete(res.length() - 2, res.length() - 1);
499       res.append("]");
500       return res.toString();
501     }
502 
503     JButton fileButton;
504     JButton listButton;
505     JComboBox combo;
506     JPanel textButtonBox;
507   }//class ObjectRenderer extends DefaultTableCellRenderer
508 
509   class ParameterDisjunctionEditor extends DefaultCellEditor{
510     public ParameterDisjunctionEditor(){
511       super(new JComboBox());
512       combo = (JComboBox)super.getComponent();
513       class CustomRenderer extends JLabel implements ListCellRenderer {
514         public CustomRenderer(){
515           setOpaque(true);
516         }
517         public Component getListCellRendererComponent(JList list,
518                                                       Object value,
519                                                       int index,
520                                                       boolean isSelected,
521                                                       boolean cellHasFocus){
522           if (isSelected) {
523               setBackground(list.getSelectionBackground());
524               setForeground(list.getSelectionForeground());
525           }
526           else {
527               setBackground(list.getBackground());
528               setForeground(list.getForeground());
529           }
530 
531           setFont(list.getFont());
532 
533           setText((String)value);
534 
535           String iconName = "param.gif";
536           Parameter[] params = pDisj.getParameters();
537           for(int i = 0; i < params.length; i++){
538             Parameter param = (Parameter)params[i];
539             if(param.getName().equals(value)){
540               String type = param.getTypeName();
541               if(Gate.getCreoleRegister().containsKey(type)){
542                 ResourceData rData = (ResourceData)
543                                      Gate.getCreoleRegister().get(type);
544                 if(rData != null) iconName = rData.getIcon();
545               }
546               break;
547             }//if(params[i].getName().equals(value))
548           }//for(int i = 0; params.length; i++)
549 
550           setIcon(MainFrame.getIcon(iconName));
551           return this;
552         }
553       };//class CustomRenderer extends JLabel implements ListCellRenderer
554       combo.setRenderer(new CustomRenderer());
555       combo.addActionListener(new ActionListener() {
556         public void actionPerformed(ActionEvent e) {
557           stopCellEditing();
558         }
559       });
560     }// public ParameterDisjunctionEditor()
561 
562     public Component getTableCellEditorComponent(JTable table,
563                                              Object value,
564                                              boolean isSelected,
565                                              int row,
566                                              int column){
567      pDisj = (ParameterDisjunction)value;
568      combo.setModel(new DefaultComboBoxModel(pDisj.getNames()));
569      return combo;
570     }// public Component getTableCellEditorComponent
571 
572     public Object getCellEditorValue(){
573       return new Integer(combo.getSelectedIndex());
574     }
575 
576     public boolean stopCellEditing(){
577       combo.hidePopup();
578       return super.stopCellEditing();
579     }
580 
581     JComboBox combo;
582     ParameterDisjunction pDisj;
583   }// class ParameterDisjunctionEditor extends DefaultCellEditor
584 
585   class ParameterValueEditor extends AbstractCellEditor
586                              implements TableCellEditor{
587     ParameterValueEditor(){
588       combo = new JComboBox();
589       combo.setRenderer(new ResourceRenderer());
590       combo.setEditable(false);
591 
592       textField = new JTextField();
593 
594       fileChooser = MainFrame.getFileChooser();
595       fileButton = new JButton(MainFrame.getIcon("loadFile.gif"));
596       fileButton.setToolTipText("Set from file...");
597       fileButton.addActionListener(new ActionListener() {
598         public void actionPerformed(ActionEvent e) {
599           fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
600           fileChooser.setDialogTitle("Select a file");
601           int res = fileChooser.showOpenDialog(ResourceParametersEditor.this);
602           if(res == fileChooser.APPROVE_OPTION){
603             try {
604               textField.setText(fileChooser.getSelectedFile().
605                                 toURL().toExternalForm());
606             } catch(IOException ioe){}
607             fireEditingStopped();
608           }else{
609             fireEditingCanceled();
610           }
611         }
612       });
613 
614       listButton = new JButton(MainFrame.getIcon("editList.gif"));
615       listButton.setToolTipText("Edit the list");
616       listButton.addActionListener(new ActionListener() {
617         public void actionPerformed(ActionEvent e) {
618           List returnedList = listEditor.showDialog();
619           if(returnedList != null){
620             listValue = returnedList;
621             fireEditingStopped();
622           }else{
623             fireEditingCanceled();
624           }
625         }
626       });
627 
628       textButtonBox = new JPanel();
629       textButtonBox.setLayout(new BoxLayout(textButtonBox, BoxLayout.X_AXIS));
630       textButtonBox.setOpaque(false);
631       label = new JLabel(){
632         public boolean isFocusable(){
633           return true;
634         }
635       };
636       label.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
637       label.addMouseListener(new MouseAdapter() {
638         public void mouseClicked(MouseEvent e) {
639           Boolean value = new Boolean(label.getText());
640           value = new Boolean(!value.booleanValue());
641           label.setText(value.toString());
642         }
643       });
644       label.addKeyListener(new KeyAdapter() {
645         public void keyTyped(KeyEvent e) {
646           Boolean value = new Boolean(label.getText());
647           value = new Boolean(!value.booleanValue());
648           label.setText(value.toString());
649         }
650       });
651 
652       textButtonBox.addFocusListener(new FocusAdapter() {
653         public void focusGained(FocusEvent e) {
654           if(comboUsed){
655 
656           }else{
657             textField.requestFocusInWindow();
658           }
659         }
660 
661         public void focusLost(FocusEvent e) {
662         }
663       });
664 
665     }//ParameterValueEditor()
666 
667     public Component getTableCellEditorComponent(JTable table,
668                                                  Object value,
669                                                  boolean isSelected,
670                                                  int row,
671                                                  int column){
672       comboUsed = false;
673       listUsed = false;
674       ParameterDisjunction pDisj = (ParameterDisjunction)
675                                    table.getValueAt(row, 0);
676       type = pDisj.getType();
677 //      ResourceData rData = (ResourceData)Gate.getCreoleRegister().get(type);
678 
679       if(Gate.isGateType(type)){
680         //Gate type
681         comboUsed = true;
682         ArrayList values = new ArrayList();
683         try{
684           values.addAll(Gate.getCreoleRegister().
685                         getAllInstances(type));
686         }catch(GateException ge){
687           ge.printStackTrace(Err.getPrintWriter());
688         }
689         values.add(0, "<none>");
690         combo.setModel(new DefaultComboBoxModel(values.toArray()));
691         combo.setSelectedItem(value == null ? "<none>" : value);
692         return combo;
693       }else{
694         //non Gate type
695         Class typeClass = null;
696         try{
697           typeClass = Class.forName(type);
698         }catch(ClassNotFoundException cnfe){
699         }
700 
701         textField.setText((value == null) ? "" : value.toString());
702         if(type.equals("java.net.URL")){
703           //clean up all filters
704           fileChooser.resetChoosableFileFilters();
705           fileChooser.setAcceptAllFileFilterUsed(true);
706           fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter());
707           Parameter param = pDisj.getParameter();
708           Set sufixes = param.getSuffixes();
709           if(sufixes != null){
710             ExtensionFileFilter fileFilter = new ExtensionFileFilter();
711             Iterator sufIter = sufixes.iterator();
712             while(sufIter.hasNext()){
713               fileFilter.addExtension((String)sufIter.next());
714             }
715             fileFilter.setDescription("Known file types " + sufixes.toString());
716             fileChooser.addChoosableFileFilter(fileFilter);
717             fileChooser.setFileFilter(fileFilter);
718           }
719 
720           textField.setEditable(true);
721           textButtonBox.removeAll();
722           textButtonBox.add(textField);
723           textButtonBox.add(Box.createHorizontalStrut(5));
724           textButtonBox.add(fileButton);
725           return textButtonBox;
726         }else if(type.equals("java.lang.Boolean")){
727           label.setText(value == null ? "false" : value.toString());
728           return label;
729         }else if(typeClass != null &&
730                       List.class.isAssignableFrom(typeClass)){
731           //List value
732           listUsed = true;
733           Parameter param = pDisj.getParameter();
734           Set sufixes = param.getSuffixes();
735 
736           listValue = (List)value;
737           listEditor = new ListEditorDialog(
738                 SwingUtilities.getAncestorOfClass(
739                 Window.class, ResourceParametersEditor.this),
740                 (List)value, param.getItemClassName());
741 
742           textField.setEditable(false);
743           textField.setText(textForList((List)value));
744           textButtonBox.removeAll();
745           textButtonBox.add(textField);
746           textButtonBox.add(Box.createHorizontalStrut(5));
747           textButtonBox.add(listButton);
748           return textButtonBox;
749         }else{
750           textField.setEditable(true);
751           return textField;
752         }
753       }
754     }//getTableCellEditorComponent
755 
756     /**
757      * Gets a string representation for a list value
758      */
759     protected String textForList(List list){
760       if(list == null || list.isEmpty()) return "[]";
761       StringBuffer res = new StringBuffer("[");
762       Iterator elemIter = list.iterator();
763       while(elemIter.hasNext()){
764         Object elem = elemIter.next();
765         res.append( ((elem instanceof NameBearer) ?
766                     ((NameBearer)elem).getName() :
767                     elem.toString()) + ", ");
768       }
769       res.delete(res.length() - 2, res.length() - 1);
770       res.append("]");
771       return res.toString();
772     }
773 
774     public Object getCellEditorValue(){
775       if(comboUsed){
776         Object value = combo.getSelectedItem();
777          return value == "<none>" ? null : value;
778       }
779       else if(listUsed){
780         return listValue;
781       }else{
782         if(type.equals("java.lang.Boolean")){
783           //get the value from the label
784           return new Boolean(label.getText());
785         }else{
786           //get the value from the text field
787           return textField.getText();
788 //          return ((textField.getText().equals("")) ? null :
789 //                                                     textField.getText());
790         }
791       }
792     }//public Object getCellEditorValue()
793 
794     /**
795      * The type of the value currently being edited
796      */
797     String type;
798 
799     /**
800      * Combobox use as editor for Gate objects (chooses between instances)
801      */
802     JComboBox combo;
803 
804     /**
805      * Editor used for boolean values
806      */
807     JLabel label;
808 
809     /**
810      * Generic editor for all types that are not treated special
811      */
812     JTextField textField;
813 
814     /**
815      * A pointer to the filechooser from MainFrame;
816      */
817     JFileChooser fileChooser;
818 
819     ListEditorDialog listEditor = null;
820     List listValue;
821 
822     boolean comboUsed;
823     boolean listUsed;
824     JButton fileButton;
825     JButton listButton;
826     JPanel textButtonBox;
827   }///class ParameterValueEditor
828 }//class NewResourceDialog