FeaturesEditor.java
001 /*
002  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
003  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
004  *
005  *  This file is part of GATE (see http://gate.ac.uk/), and is free
006  *  software, licenced under the GNU Library General Public License,
007  *  Version 2, June 1991 (in the distribution as file licence.html,
008  *  and also available at http://gate.ac.uk/gate/licence.html).
009  *
010  *  Valentin Tablan 23/01/2001
011  *
012  *  $Id: FeaturesEditor.java 12260 2010-02-15 16:37:49Z valyt $
013  *
014  */
015 
016 package gate.gui;
017 
018 import java.awt.*;
019 import java.awt.event.ActionEvent;
020 import java.awt.event.ActionListener;
021 import java.util.*;
022 import java.util.List;
023 
024 import javax.swing.*;
025 import javax.swing.table.AbstractTableModel;
026 import javax.swing.table.DefaultTableCellRenderer;
027 
028 import gate.Factory;
029 import gate.FeatureMap;
030 import gate.creole.AbstractVisualResource;
031 import gate.swing.XJTable;
032 import gate.util.FeatureBearer;
033 
034 public class FeaturesEditor extends AbstractVisualResource{
035 
036   public FeaturesEditor() {
037     initLocalData();
038     initGuiComponents();
039     initListeners();
040   }// FeaturesEditor()
041 
042   protected void initLocalData(){
043     features = Factory.newFeatureMap();
044   }
045 
046   protected void initGuiComponents(){
047     this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
048     tableModel = new FeaturesTableModel();
049     table = new XJTable(tableModel);
050 //    table.setIntercellSpacing(new Dimension(5,5));
051     table.setDefaultRenderer(String.class, new DefaultTableCellRenderer());
052     table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer());
053     table.setAutoResizeMode(XJTable.AUTO_RESIZE_OFF);
054     DefaultCellEditor editor = new DefaultCellEditor(new JTextField());
055     editor.setClickCountToStart(0);
056     table.setDefaultEditor(String.class, editor);
057     table.setDefaultEditor(Object.class, editor);
058 
059     JScrollPane scroll = new JScrollPane(table);
060     scroll.getViewport().setOpaque(true);
061     //the background colour seems to change somewhere when using the GTK+ 
062     //look and feel on Linux, so we copy the value now and set it 
063     Color tableBG = table.getBackground();
064     //make a copy of the value (as the reference gets changed somewhere)
065     tableBG = new Color(tableBG.getRGB());
066     table.setBackground(tableBG);
067     scroll.getViewport().setBackground(tableBG);
068     this.add(scroll, BorderLayout.CENTER);
069     this.add(Box.createVerticalStrut(5));
070 
071     Box box = Box.createHorizontalBox();
072     newFeatureField = new JTextField(10);
073     newFeatureField.setMaximumSize(new Dimension(Integer.MAX_VALUE,
074                                                  newFeatureField.
075                                                  getPreferredSize().height));
076 
077     Box vBox = Box.createVerticalBox();
078     vBox.add(new JLabel("New feature name"));
079     vBox.add(newFeatureField);
080     box.add(vBox);
081     box.add(Box.createHorizontalStrut(5));
082 
083     newValueField = new JTextField(10);
084     newValueField.setMaximumSize(new Dimension(Integer.MAX_VALUE,
085                                                  newValueField.
086                                                  getPreferredSize().height));
087 
088     vBox = Box.createVerticalBox();
089     vBox.add(new JLabel("New feature value"));
090     vBox.add(newValueField);
091     box.add(vBox);
092     box.add(Box.createHorizontalStrut(5));
093 
094     addNewBtn = new JButton("Add feature");
095     box.add(addNewBtn);
096     box.add(Box.createHorizontalStrut(5));
097 
098     delBtn = new JButton("Delete");
099     box.add(delBtn);
100 
101     this.add(box);
102     this.add(Box.createVerticalGlue());
103 
104   }// protected void initGuiComponents()
105 
106   protected void initListeners(){
107     addNewBtn.addActionListener(new ActionListener() {
108       public void actionPerformed(ActionEvent e) {
109         String name = newFeatureField.getText();
110         String value = newValueField.getText();
111         if(name != null){
112           features.put(name, value);
113           tableModel.fireTableDataChanged();
114           newFeatureField.setText("");
115           newValueField.setText("");
116         }
117       }
118     });
119 
120     delBtn.addActionListener(new ActionListener() {
121       public void actionPerformed(ActionEvent e) {
122         String name = newFeatureField.getText();
123         String value = newValueField.getText();
124         if(name != null){
125           features.remove(name);
126           tableModel.fireTableDataChanged();
127           newFeatureField.setText("");
128           newValueField.setText("");
129         }
130       }
131     });
132   }
133 
134   public void cleanup(){
135     super.cleanup();
136     features = null;
137     resource = null;
138   }
139 
140   public void setFeatureBearer(FeatureBearer newResource) {
141     if(newResource == null){
142       resource = null;
143       features = null;
144     }else{
145       resource = newResource;
146       features = resource.getFeatures();
147     }
148     tableModel.fireTableDataChanged();
149   }// public void setFeatureBearer(FeatureBearer newResource)
150 
151   public void setTarget(Object target) {
152     if(target == null || target instanceof FeatureBearer){
153       setFeatureBearer((FeatureBearer)target);
154     }else{
155       throw new IllegalArgumentException(
156         "FeatureEditors can only be used with FeatureBearer!\n" +
157         target.getClass().toString() " is not a FeatureBearer!");
158     }
159   }//public void setResource(Resource resource)
160 
161   public void setHandle(Handle handle){
162     //NOP
163   }
164 
165 
166   public FeatureBearer getFeatureBearer() {
167     return resource;
168   }
169 
170   XJTable table;
171   FeaturesTableModel tableModel;
172   private FeatureBearer resource;
173   FeatureMap features;
174   JTextField newFeatureField;
175   JTextField newValueField;
176 
177   JButton addNewBtn;
178   JButton delBtn;
179 
180   class FeaturesTableModel extends AbstractTableModel{
181     public int getColumnCount(){
182       return 2;
183     }
184 
185     public int getRowCount(){
186       return features == null : features.size();
187     }
188 
189     public String getColumnName(int columnIndex){
190       switch(columnIndex){
191         case 0return "Feature";
192         case 1return "Value";
193         defaultreturn "?";
194       }
195     }//public String getColumnName(int columnIndex)
196 
197     public Class getColumnClass(int columnIndex){
198       switch(columnIndex){
199         case 0return String.class;
200         case 1return Object.class;
201         defaultreturn Object.class;
202       }
203     }
204 
205     public boolean isCellEditable(int rowIndex,
206                               int columnIndex){
207       if(features == nullreturn false;
208       return rowIndex == features.size()
209              ||
210              ((!((String)table.getModel().getValueAt(rowIndex, 0)).
211               startsWith("gate."))
212              );
213     }// public boolean isCellEditable
214 
215     public Object getValueAt(int rowIndex,
216                          int columnIndex){
217       if(features == nullreturn null;
218       List keys = new ArrayList(features.keySet());
219       Collections.sort(keys);
220       Object key = keys.get(rowIndex);
221       switch(columnIndex){
222         case 0:{
223           return key;
224         }
225         case 1:{
226           return features.get(key== null "" : features.get(key).toString();
227         }
228         default:{
229           return null;
230         }
231       }
232     }// public Object getValueAt
233 
234     public void setValueAt(Object aValue,
235                        int rowIndex,
236                        int columnIndex){
237 
238       if(columnIndex == 0) {
239         //the name of the feature changed
240         //if the name is null or empty the feature will be deleted
241         String oldName = (String)getValueAt(rowIndex, 0);
242         Object oldValue = features.remove(oldName);
243         if(aValue != null && !aValue.equals("")){
244           features.put(aValue, oldValue);
245         }
246       else {
247         //the value of a feature changed
248         features.put(getValueAt(rowIndex, 0), aValue);
249       }
250       fireTableDataChanged();
251     }// public void setValueAt
252 
253   }///class FeaturesTableModel extends DefaultTableModel
254 /*
255   class FeaturesTableRenderer extends DefaultTableCellRenderer{
256     public Component getTableCellRendererComponent(JTable table,
257                                                    Object value,
258                                                    boolean isSelected,
259                                                    boolean hasFocus,
260                                                    int row,
261                                                    int column){
262 
263       super.getTableCellRendererComponent(table, value, false, hasFocus,
264                                           row, column);
265       setEnabled(table.isCellEditable(row, column));
266       return this;
267     }
268 
269   }// class FeaturesTableRenderer
270 */
271 }// class FeaturesEditor