| SchemaAnnotationEditor |

    1   /*  SchemaAnnotationEditor.java
    2    *
    3    *  Copyright (c) 1998-2001, The University of Sheffield.
    4    *
    5    *  This file is part of GATE (see http://gate.ac.uk/), and is free
    6    *  software, licenced under the GNU Library General Public License,
    7    *  Version 2, June 1991 (in the distribution as file licence.html,
    8    *  and also available at http://gate.ac.uk/gate/licence.html).
    9    *
    10   *  Cristian URSU,  12/July/2001
    11   *
    12   *  $Id: SchemaAnnotationEditor.java,v 1.12 2001/11/05 16:07:48 valyt Exp $
    13   *
    14   */
    15
    16  package gate.gui;
    17
    18  import java.awt.Frame;
    19  import java.awt.BorderLayout;
    20  import java.awt.Component;
    21  import java.awt.event.*;
    22  import javax.swing.*;
    23  import javax.swing.table.*;
    24
    25  import java.util.*;
    26  import java.lang.reflect.*;
    27
    28  import gate.*;
    29  import gate.annotation.*;
    30  import gate.util.*;
    31  import gate.creole.*;
    32
    33  /** This class is a viewer which adds/edits features on a GATE annotation.
    34    * This viewer is {@link gate.creole.AnnotationSchema} driven.
    35    */
    36  public class SchemaAnnotationEditor extends AbstractVisualResource
    37                                      implements AnnotationVisualResource{
    38
    39    /** Default constructor */
    40    public SchemaAnnotationEditor(){}
    41
    42    // Methods required by AnnotationVisualResource
    43
    44    /**
    45      * Called by the GUI when this viewer/editor has to initialise itself for a
    46      * specific annotation or text span.
    47      * @param target the object which will always be a {@link gate.AnnotationSet}
    48      */
    49    public void setTarget(Object target){
    50      currentAnnotSet = (AnnotationSet) target;
    51    }// setTarget();
    52
    53    /**
    54      * Used when the viewer/editor has to display/edit an existing annotation
    55      * @param ann the annotation to be displayed or edited. If ann is null then
    56      * the method simply returns
    57      */
    58    public void setAnnotation(Annotation ann){
    59      // If ann is null, then simply return.
    60      if (ann == null) return;
    61
    62      currentAnnot = ann;
    63      currentStartOffset = currentAnnot.getStartNode().getOffset();
    64      currentEndOffset = currentAnnot.getEndNode().getOffset();
    65      currentAnnotFeaturesMap = Factory.newFeatureMap();
    66      currentAnnotFeaturesMap.putAll(currentAnnot.getFeatures());
    67      currentAnnotSchema = null;
    68      CreoleRegister creoleReg = Gate.getCreoleRegister();
    69      List currentAnnotationSchemaList =
    70                        creoleReg.getLrInstances("gate.creole.AnnotationSchema");
    71      // If there is no Annotation schema loaded the editor can only do nothing
    72      if (currentAnnotationSchemaList.isEmpty()) return;
    73      name2annotSchemaMap = new TreeMap();
    74      Iterator annotSchemaIter = currentAnnotationSchemaList.iterator();
    75      // currentAnnotationSchemaList is not empty
    76      currentAnnotSchema = (AnnotationSchema) currentAnnotationSchemaList.get(0);
    77      while (annotSchemaIter.hasNext()){
    78        AnnotationSchema annotSch = (AnnotationSchema)annotSchemaIter.next();
    79        name2annotSchemaMap.put(annotSch.getAnnotationName(),annotSch);
    80        if (currentAnnot.getType().equals(annotSch.getAnnotationName()))
    81          currentAnnotSchema = annotSch;
    82      }// End while
    83
    84      initLocalData();
    85      buildGuiComponents();
    86      initListeners();
    87    }// setAnnotation();
    88
    89    /**
    90      * Used when the viewer has to create new annotations.
    91      * @param startOffset the start offset of the span covered by the new
    92      * annotation(s). If is <b>null</b> the method will simply return.
    93      * @param endOffset the end offset of the span covered by the new
    94      * annotation(s). If is <b>null</b> the method will simply return.
    95      */
    96    public void setSpan(Long startOffset, Long endOffset, String annotType){
    97      // If one of them is null, then simply return.
    98      if (startOffset == null || endOffset == null) return;
    99      currentStartOffset = startOffset;
    100     currentEndOffset = endOffset;
    101     currentAnnot = null;
    102     currentAnnotFeaturesMap = null;
    103     currentAnnotSchema = null;
    104     CreoleRegister creoleReg = Gate.getCreoleRegister();
    105     List currentAnnotationSchemaList = null;
    106     try{
    107       currentAnnotationSchemaList =
    108               creoleReg.getAllInstances("gate.creole.AnnotationSchema");
    109     } catch (GateException e){
    110       // This exception shouldn't happen. If it happens then something went
    111       // terribly wrong.
    112       throw new LuckyException("gate.creole.AnnotationSchema or a class that"+
    113       " extends it, is not registered in the creole.xml register.Edit your"+
    114       " creole.xml and try again.");
    115     }// End try
    116     // If there is no Annotation schema loaded, the editor can only do nothing
    117     if (currentAnnotationSchemaList.isEmpty()) return;
    118     name2annotSchemaMap = new TreeMap();
    119     Iterator annotSchemaIter = currentAnnotationSchemaList.iterator();
    120     // currentAnnotationSchemaList is not empty (see the above comment)
    121     currentAnnotSchema = (AnnotationSchema) currentAnnotationSchemaList.get(0);
    122     while (annotSchemaIter.hasNext()){
    123       AnnotationSchema annotSch = (AnnotationSchema)annotSchemaIter.next();
    124       name2annotSchemaMap.put(annotSch.getAnnotationName(),annotSch);
    125     }// End while
    126
    127     initLocalData();
    128     buildGuiComponents();
    129     initListeners();
    130   }// setSpan();
    131
    132   /**
    133    * Called by the GUI when the user has pressed the "OK" button. This should
    134    * trigger the saving of the newly created annotation(s)
    135    */
    136   public void okAction() throws GateException{
    137     // Construct the response featutre
    138     Iterator iter = tableModel.data.iterator();
    139     while (iter.hasNext()){
    140       RowData rd = (RowData) iter.next();
    141       responseMap.put(rd.getFeatureSchema().getFeatureName(), rd.getValue());
    142     }// End while
    143     if (currentAnnot == null){
    144       currentAnnotSet.add( currentStartOffset,
    145                            currentEndOffset,
    146                            currentAnnotSchema.getAnnotationName(),
    147                            responseMap);
    148     }else{
    149       if (currentAnnot.getType().equals(currentAnnotSchema.getAnnotationName())){
    150         currentAnnot.setFeatures(responseMap);
    151       }else{
    152         currentAnnotSet.add( currentStartOffset,
    153                              currentEndOffset,
    154                              currentAnnotSchema.getAnnotationName(),
    155                              responseMap);
    156         currentAnnotSet.remove(currentAnnot);
    157       }// End if
    158     }// End if
    159   }//okAction();
    160
    161   public void cancelAction() throws GateException {
    162     //no need for any cleanup, because this editor has been implemented
    163     //so that it does not modify the document and annotations, unless
    164     //OK is pressed
    165     return;
    166   }
    167
    168   /**
    169     * Checks whether this viewer/editor can handle a specific annotation type.
    170     * @param annotationType represents the annotation type being questioned.If
    171     * it is <b>null</b> then the method will return false.
    172     * @return true if the SchemaAnnotationEditor can handle the annotationType
    173     * or false otherwise.
    174     */
    175   public boolean canDisplayAnnotationType(String annotationType){
    176     // Returns true only if the there is an AnnotationSchema with the same type
    177     // as annotationType.
    178     if (annotationType == null) return false;
    179     CreoleRegister creoleReg = Gate.getCreoleRegister();
    180     List currentAnnotationSchemaList =
    181                       creoleReg.getLrInstances("gate.creole.AnnotationSchema");
    182     if (currentAnnotationSchemaList.isEmpty()) return false;
    183     Iterator iter = currentAnnotationSchemaList.iterator();
    184     while (iter.hasNext()){
    185       AnnotationSchema annotSchema = (AnnotationSchema) iter.next();
    186       if (annotationType.equals(annotSchema.getAnnotationName())) return true;
    187     }// End while
    188     return false;
    189   }// canDisplayAnnotationType();
    190
    191   // The Schema Editor functionality
    192
    193   // Local data
    194   /** The annotation schema present into the system*/
    195   List currentAnnotationSchemaList = null;
    196   /** The curent annotation set used by the editor*/
    197   AnnotationSet currentAnnotSet = null;
    198   /** The curent annotation used by the editor*/
    199   Annotation currentAnnot = null;
    200   /** The start offset of the span covered by the currentAnnot*/
    201   Long currentStartOffset = null;
    202   /** The end offset of the span covered by the currentAnnot*/
    203   Long currentEndOffset = null;
    204   /** This is the currentAnnotSchema being used by the editor*/
    205   AnnotationSchema currentAnnotSchema = null;
    206   /** The current FeatureMap used by the editor*/
    207   FeatureMap currentAnnotFeaturesMap = null;
    208   /** This field is returned when a featureMap was editted or created*/
    209   FeatureMap responseMap = null;
    210   /** This field is the table model used to represent features*/
    211   FeaturesTableModel tableModel = null;
    212   /** A map from feature name to its FeatureSchema definition*/
    213   Map name2featureSchemaMap = null;
    214   /** A map from annotation type to its AnnotationSchema definition*/
    215   Map name2annotSchemaMap = null;
    216   /** A list model used to represent the features not assigned to an annot*/
    217   DefaultListModel listModel = null;
    218
    219   // Gui Components
    220   /** Displays the current features of the annotation being editted */
    221   JTable  featuresTable = null;
    222   /** A JScroll for the featuresTable component */
    223   JScrollPane featuresTableScroll = null;
    224   /** Displays all possible features of the annotation being
    225    *  editted (taken from AnnotationSchema)
    226    */
    227   JList   featureSchemaList = null;
    228   /** A JScroll for the featuresTable component */
    229   JScrollPane featuresListScroll = null;
    230   /** This button removes current features and add them to possible feature list*/
    231   JButton removeFeatButton = null;
    232   /** This button does the opposite of the above*/
    233   JButton addFeatButton = null;
    234   /** Displays all possible annotation schema loaded into the system*/
    235   JComboBox annotSchemaComboBox = null;
    236   /** This inner class deals with feature editting*/
    237   InnerFeaturesEditor featuresEditor = null;
    238
    239   /** Init local data needed by the GUI components to initialize*/
    240   protected void initLocalData(){
    241     // Create the response feature Map
    242     responseMap = Factory.newFeatureMap();
    243
    244     if (currentAnnotFeaturesMap == null)
    245       currentAnnotFeaturesMap = Factory.newFeatureMap();
    246
    247     name2featureSchemaMap = new HashMap();
    248     // Construct a set of feature names from feature schema
    249     Map fSNames2FSMap = new HashMap();
    250
    251     listModel = new DefaultListModel();
    252     // Init name2featureSchemaMap
    253     // If the feature map provided was null, then we are in the creation mode
    254     Set featuresSch = currentAnnotSchema.getFeatureSchemaSet();
    255     if (featuresSch != null){
    256       Iterator iter = featuresSch.iterator();
    257       while (iter.hasNext()){
    258         FeatureSchema fs = (FeatureSchema) iter.next();
    259         // If the currentAnnotFeaturesMap doesn't contain the feature
    260         // from FeatureSchema then
    261         // add the featureSchema to the list
    262         if (fs != null){
    263           fSNames2FSMap.put(fs.getFeatureName(),fs);
    264           if( !currentAnnotFeaturesMap.containsKey(fs.getFeatureName())){
    265               name2featureSchemaMap.put(fs.getFeatureName(),fs);
    266               listModel.addElement(fs.getFeatureName());
    267           }// end if
    268         }// end if
    269       }// end while
    270     }// end if
    271
    272     // Init the table model
    273     Set tableData = new HashSet();
    274     Iterator iterator = currentAnnotFeaturesMap.keySet().iterator();
    275     while (iterator.hasNext()){
    276       String key = (String) iterator.next();
    277       // If in currentAnnotFeaturesMap there is a key contained into
    278       // fSNames2FSMap then
    279       // add this feature to the table model together with its corresponding
    280       // FeatureSchema
    281       if (fSNames2FSMap.keySet().contains(key)){
    282         // Add it to the table model
    283         Object value = currentAnnotFeaturesMap.get(key);
    284         tableData.add(new RowData(value,(FeatureSchema)fSNames2FSMap.get(key)));
    285       } else
    286         // Add it to the responseFeatureMap
    287         // It might be a feature detected by the nameMatcher module, etc.
    288         // Those features must be preserved.
    289         responseMap.put(key,currentAnnotFeaturesMap.get(key));
    290     }// end while
    291     tableModel = new FeaturesTableModel(tableData);
    292   }// initLocalData();
    293
    294   /** This method creates the GUI components and paces them into the layout*/
    295   protected void buildGuiComponents(){
    296     this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
    297     // Create the annotationSchema JComboBox box
    298
    299     JPanel annotSchBox = new JPanel();
    300     annotSchBox.setLayout(new BoxLayout(annotSchBox, BoxLayout.Y_AXIS));
    301     annotSchBox.setAlignmentX(Component.LEFT_ALIGNMENT);
    302     annotSchBox.add(Box.createVerticalStrut(5));
    303     annotSchemaComboBox = new JComboBox(name2annotSchemaMap.keySet().toArray());
    304     annotSchemaComboBox.setEditable(false);
    305     annotSchemaComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
    306     annotSchemaComboBox.setSelectedItem(currentAnnotSchema.getAnnotationName());
    307     JLabel annotSchemaLabel = new JLabel("Select annotation type");
    308     annotSchemaLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
    309     annotSchBox.add(annotSchemaLabel);
    310     annotSchBox.add(annotSchemaComboBox);
    311
    312
    313     //Create the main box
    314     JPanel componentsBox = new JPanel();
    315     componentsBox.setLayout(new BoxLayout(componentsBox, BoxLayout.X_AXIS));
    316     componentsBox.setAlignmentX(Component.LEFT_ALIGNMENT);
    317
    318     // Create the feature table
    319     featuresTable = new JTable();
    320     featuresTable.setSelectionMode(
    321                   ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    322     featuresTable.setModel(new FeaturesTableModel(new HashSet()));
    323     featuresTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
    324     featuresEditor = new InnerFeaturesEditor();
    325     featuresTable.setDefaultEditor(java.lang.Object.class, featuresEditor);
    326     featuresTableScroll = new JScrollPane(featuresTable);
    327
    328     Box box = Box.createVerticalBox();
    329     JLabel currentFeat = new JLabel("Current features");
    330     currentFeat.setAlignmentX(Component.LEFT_ALIGNMENT);
    331     box.add(currentFeat);
    332     box.add(Box.createVerticalStrut(10));
    333     box.add(featuresTableScroll);
    334     featuresTableScroll.setAlignmentX(Component.LEFT_ALIGNMENT);
    335
    336     componentsBox.add(box);
    337     componentsBox.add(Box.createHorizontalStrut(10));
    338
    339     // add the remove put buttons
    340     Box buttBox = Box.createVerticalBox();
    341     removeFeatButton = new JButton(">>");
    342     addFeatButton = new JButton("<<");
    343
    344     buttBox.add(addFeatButton);
    345     buttBox.add(Box.createVerticalStrut(10));
    346     buttBox.add(removeFeatButton);
    347
    348     componentsBox.add(buttBox);
    349
    350     componentsBox.add(Box.createHorizontalStrut(10));
    351
    352     // add the Feature Schema list
    353     featureSchemaList = new JList();
    354     featureSchemaList.setSelectionMode(
    355                   ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    356     Set featuresSch = currentAnnotSchema.getFeatureSchemaSet();
    357     if(featuresSch != null){
    358       featureSchemaList.setVisibleRowCount(featuresSch.size());
    359     }
    360     featuresListScroll = new JScrollPane(featureSchemaList);
    361
    362     box = Box.createVerticalBox();
    363     JLabel possibFeaturesLabel = new JLabel("Possible features");
    364     possibFeaturesLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
    365     box.add(possibFeaturesLabel);
    366     box.add(Box.createVerticalStrut(10));
    367     featuresListScroll.setAlignmentX(Component.LEFT_ALIGNMENT);
    368     box.add(featuresListScroll);
    369
    370     componentsBox.add(box);
    371     componentsBox.add(Box.createHorizontalStrut(5));
    372
    373     box = Box.createVerticalBox();
    374     box.add(annotSchBox);
    375     box.add(componentsBox);
    376     this.add(box);
    377     this.initGuiComponents();
    378   }//buildGuiComponents();
    379
    380   /** Init GUI components with values taken from local data*/
    381   protected void initGuiComponents(){
    382     featuresTable.setModel(tableModel);
    383     featureSchemaList.setModel(listModel);
    384   }//initGuiComponents()
    385
    386   /** Init all the listeners*/
    387   protected void initListeners(){
    388
    389     annotSchemaComboBox.addActionListener(new ActionListener() {
    390       public void actionPerformed(ActionEvent e) {
    391         currentAnnotSchema = (AnnotationSchema) name2annotSchemaMap.get(
    392                                  (String)annotSchemaComboBox.getSelectedItem());
    393         initLocalData();
    394         initGuiComponents();
    395       }// actionPerformed();
    396     });//addActionListener();
    397
    398     // -> removeFeatButton
    399     removeFeatButton.addActionListener(new ActionListener() {
    400       public void actionPerformed(ActionEvent e) {
    401         doRemoveFeatures();
    402       }//actionPerformed();
    403     });// addActionListener();
    404
    405     // <- addFeatButton
    406     addFeatButton.addActionListener(new ActionListener() {
    407       public void actionPerformed(ActionEvent e) {
    408         doAddFeatures();
    409       }// actionPerformed();
    410     });// addActionListener();
    411   }//initListeners()
    412
    413   /** This method remove a feature from the table and adds it to the list*/
    414   private void doRemoveFeatures(){
    415     int[] selectedRows = featuresTable.getSelectedRows();
    416
    417     if (selectedRows.length <= 0) return;
    418
    419     for (int i = (selectedRows.length - 1); i > -1 ; i--)
    420       doRemoveFeature(selectedRows[i]);
    421
    422     tableModel.fireTableDataChanged();
    423   }// doRemoveFeatures();
    424
    425   /** This removes the feature @ rowIndex*/
    426   private void doRemoveFeature(int rowIndex){
    427     RowData rd =  (RowData) tableModel.data.get(rowIndex);
    428
    429     name2featureSchemaMap.put(rd.getFeatureSchema().getFeatureName(),
    430                                                       rd.getFeatureSchema());
    431
    432     listModel.addElement(rd.getFeatureSchema().getFeatureName());
    433     tableModel.data.remove(rowIndex);
    434   }// doRemoveFeature();
    435
    436   /** This method adds features from the list to the table*/
    437   private void doAddFeatures(){
    438     Object[] selectedFeaturesName = featureSchemaList.getSelectedValues();
    439     for (int i = 0 ; i < selectedFeaturesName.length; i ++){
    440       doAddFeature((String) selectedFeaturesName[i]);
    441     }// end for
    442     tableModel.fireTableDataChanged();
    443   }//doAddFeatures();
    444
    445   /** This method adds a feature from the list to the table*/
    446   private void doAddFeature(String aFeatureName){
    447       FeatureSchema fs=(FeatureSchema) name2featureSchemaMap.get(aFeatureName);
    448
    449       // Remove the feature schema from the list
    450       name2featureSchemaMap.remove(aFeatureName);
    451       listModel.removeElement(aFeatureName);
    452
    453       Object value = null;
    454       if (fs.isDefault() || fs.isFixed())
    455         value = fs.getFeatureValue();
    456       if (value == null && fs.isEnumeration()){
    457         Iterator iter = fs.getPermissibleValues().iterator();
    458         if (iter.hasNext()) value = iter.next();
    459       }
    460       tableModel.data.add(new RowData(value,fs));
    461   }// doAddFeature();
    462
    463   // Inner classes
    464
    465   // TABLE MODEL
    466   protected class FeaturesTableModel extends AbstractTableModel{
    467
    468     ArrayList data = null;
    469
    470     public FeaturesTableModel(Set aData){
    471       data = new ArrayList(aData);
    472     }// FeaturesTableModel
    473
    474     public void fireTableDataChanged(){
    475       super.fireTableDataChanged();
    476     }// fireTableDataChanged();
    477
    478     public int getColumnCount(){return 3;}
    479
    480     public Class getColumnClass(int columnIndex){
    481       switch(columnIndex){
    482         case 0: return String.class;
    483         case 1: return Object.class;
    484         case 2: return String.class;
    485         default: return Object.class;
    486       }
    487     }//getColumnClass()
    488
    489     public String getColumnName(int columnIndex){
    490       switch(columnIndex){
    491         case 0: return "Name";
    492         case 1: return "Value";
    493         case 2: return "Type";
    494         default: return "?";
    495       }
    496     }//public String getColumnName(int columnIndex)
    497
    498     public boolean isCellEditable( int rowIndex,
    499                                    int columnIndex){
    500
    501
    502         if(columnIndex == 1){
    503           RowData rd = (RowData) data.get(rowIndex);
    504           FeatureSchema fs = rd.getFeatureSchema();
    505           if (fs.isFixed() || fs.isProhibited()) return false;
    506           else return true;
    507         }// end if
    508         if(columnIndex == 0 || columnIndex == 2) return false;
    509         return false;
    510     }//isCellEditable
    511
    512     public int getRowCount(){
    513       return data.size();
    514     }//getRowCount()
    515
    516     /** Returns the value at row,column from Table Model */
    517     public Object getValueAt( int rowIndex,
    518                               int columnIndex){
    519
    520       RowData rd = (RowData) data.get(rowIndex);
    521
    522       switch(columnIndex){
    523         case 0: return rd.getFeatureSchema().getFeatureName();
    524         case 1: return (rd.getValue() == null)? new String(""): rd.getValue();
    525         case 2: {
    526                   // Show only the last substring. For example, for
    527                   // java.lang.Integer -> Integer
    528                   String type = rd.getFeatureSchema().getValueClassName();
    529                   if(type == null)
    530                       return new String("");
    531                   else{
    532                     int start = type.lastIndexOf(".");
    533                     if ((start > -1) && (start < type.length()))
    534                       return type.substring(start+1,type.length());
    535                     else return type;
    536                   }// End if
    537                 }
    538
    539         default: return "?";
    540       }// End Switch
    541     }//getValueAt
    542
    543     /** Set the value from the Cell Editor into the table model*/
    544     public void setValueAt( Object aValue,
    545                             int rowIndex,
    546                             int columnIndex){
    547
    548       if (data == null || data.isEmpty()) return;
    549       RowData rd = (RowData) data.get(rowIndex);
    550       switch(columnIndex){
    551         case 0:{break;}
    552         case 1:{
    553           // Try to perform type conversion
    554           String className = null;
    555           String aValueClassName = null;
    556           // Need to create an object belonging to class "className" based on
    557           // the string object "aValue"
    558           if (aValue == null){
    559             rd.setValue("?");
    560             return;
    561           }// End if
    562           // Get the class name the final object must belong
    563           className = rd.getFeatureSchema().getValueClassName();
    564           // Get the class name that aValue object belongs to.
    565           aValueClassName = aValue.getClass().toString();
    566           // If there is no class to convert to, let the aValue object as it is
    567           // and return.
    568           if (className == null){
    569               rd.setValue(aValue);
    570               return;
    571           }// End if
    572
    573           // If both classes are the same, then return. There is nothing to
    574           // convert to
    575           if (className.equals(aValueClassName)){
    576             rd.setValue(aValue);
    577             return;
    578           }// End if
    579           // If the class "aValue" object belongs to is not String then return.
    580           // This method tries to convert a string to various other types.
    581           if (!"class java.lang.String".equals(aValueClassName)){
    582             rd.setValue(aValue);
    583             return;
    584           }// End if
    585
    586           // The aValue object belonging to java.lang.String needs to be
    587           // converted into onother object belonging to "className"
    588           Class  classObj = null;
    589           try{
    590             // Create a class object from className
    591             classObj = Gate.getClassLoader().loadClass(className);
    592           }catch (ClassNotFoundException cnfex){
    593             try{
    594               //now let's try the system classloader
    595               classObj = Class.forName(className);
    596             }catch (ClassNotFoundException cnfe){
    597             rd.setValue(aValue);
    598             return;
    599             }
    600           }// End catch
    601           // Get its list of constructors
    602           Constructor[] constrArray = classObj.getConstructors();
    603           if (constrArray == null){
    604             rd.setValue(aValue);
    605             return;
    606           }// End if
    607
    608           // Search for the constructo which takes only one String parameter
    609           boolean found = false;
    610           Constructor constructor = null;
    611           for (int i=0; i<constrArray.length; i++){
    612             constructor = constrArray[i];
    613             if ( constructor.getParameterTypes().length == 1 &&
    614                  "class java.lang.String".equals(
    615                                 constructor.getParameterTypes()[0].toString())
    616                ){
    617                   found = true;
    618                   break;
    619             }// End if
    620           }// End for
    621
    622           if (!found){
    623             rd.setValue(aValue);
    624             return;
    625           }// End if
    626           try{
    627             // Try to create an object with this constructor
    628             Object[] paramsArray = new Object[1];
    629             paramsArray[0] = aValue;
    630             Object newValueObject = constructor.newInstance(paramsArray);
    631
    632             rd.setValue(newValueObject);
    633
    634           } catch (Exception e){
    635             rd.setValue("");
    636           }// End catch
    637
    638 //          rd.setValue(aValue);
    639           break;
    640         }// End case
    641         case 2:{break;}
    642         case 3:{break;}
    643         default:{}
    644       }// End switch
    645     }// setValueAt();
    646
    647   }///class FeaturesTableModel extends DefaultTableModel
    648
    649   /** Internal class used in the inner FeaturesTableModel class*/
    650   class RowData {
    651     private Object value = null;
    652     private FeatureSchema featSchema = null;
    653
    654     /** Constructor*/
    655     RowData(Object aValue, FeatureSchema aFeatureSchema){
    656       value = aValue;
    657       featSchema = aFeatureSchema;
    658     }//RowData
    659
    660     public void setValue(Object aValue){
    661       value = aValue;
    662     }// setValue();
    663
    664     public Object getValue(){
    665       return value;
    666     }//getValue()
    667
    668     public void setFeatureSchema(FeatureSchema aFeatureSchema){
    669       featSchema = aFeatureSchema;
    670     }// setFeatureSchema();
    671
    672     public FeatureSchema getFeatureSchema(){
    673       return featSchema;
    674     }//getFeatureSchema()
    675
    676   }// RowData
    677
    678   // The EDITOR RENDERER
    679   /** This inner class deals with the feature type being eddited. What it does
    680     * is to decide what GUI component to use (JComboBox, JTextField or JLabel)
    681     */
    682   class InnerFeaturesEditor extends AbstractCellEditor  implements TableCellEditor{
    683     // Fields
    684     JComboBox cb = null;
    685     JTextField tf = null;
    686     int thisRow = 0;
    687     int thisColumn = 0;
    688     /** Constructor*/
    689     public InnerFeaturesEditor(){}
    690     /** The method overridden in order to implement behaviour*/
    691     public Component getTableCellEditorComponent( JTable table,
    692                                                   Object value,
    693                                                   boolean isSelected,
    694                                                   int row,
    695                                                   int column){
    696        thisRow = row;
    697        thisColumn = column;
    698        RowData rd = (RowData) tableModel.data.get(row);
    699        if (rd.getFeatureSchema().isEnumeration()){
    700           cb = new JComboBox(rd.getFeatureSchema().
    701                                             getPermissibleValues().toArray());
    702           cb.setSelectedItem(value);
    703           cb.addActionListener(new ActionListener(){
    704             public void actionPerformed(ActionEvent e){
    705               tableModel.setValueAt(cb.getSelectedItem(),thisRow,thisColumn);
    706             }// actionPerformed();
    707           });//addActionListener();
    708           tf = null;
    709           return cb;
    710        }// End if
    711        if ( rd.getFeatureSchema().isDefault() ||
    712             rd.getFeatureSchema().isOptional() ||
    713             rd.getFeatureSchema().isRequired() ){
    714
    715             tf = new JTextField(value.toString());
    716             cb = null;
    717             return tf;
    718        }// End iff
    719        return new JLabel(value.toString());
    720     }//getTableCellEditorComponent
    721     /** @return the object representing the value stored at that cell*/
    722     public Object getCellEditorValue(){
    723       if (cb != null ) return cb.getSelectedItem();
    724       if (tf != null ) return tf.getText();
    725       return new String("");
    726     }//getCellEditorValue
    727   }///InnerFeaturesEditor inner class
    728 }// End class SchemaAnnotationEditor

| SchemaAnnotationEditor |