| UnrestrictedAnnotationEditor.java |
1 /* UnrestrictedAnnotationEditor.java
2 *
3 * Copyright (c) 1998-2004, 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, 13/July/2001
11 *
12 * $Id: UnrestrictedAnnotationEditor.java,v 1.7 2004/07/21 17:10:07 akshay Exp $
13 *
14 */
15
16 package gate.gui;
17
18 import javax.swing.*;
19
20 import gate.*;
21 import gate.creole.AbstractVisualResource;
22 import gate.creole.AnnotationVisualResource;
23 import gate.util.*;
24
25 /** This class visually adds/edits features and annot type of an annotation
26 * It does this without using an {@link gate.creole.AnnotationSchema}.
27 * The user can manipulate annotation and features at his own will.
28 * It's his responsability.
29 */
30 public class UnrestrictedAnnotationEditor extends AbstractVisualResource
31 implements AnnotationVisualResource,
32 ResizableVisualResource{
33
34 /** Default constructor*/
35 public UnrestrictedAnnotationEditor() {}
36
37 // Methods required by AnnotationVisualResource
38
39 /**
40 * Called by the GUI when this viewer/editor has to initialise itself for a
41 * specific annotation or text span.
42 * @param target the object which will always be a {@link gate.AnnotationSet}
43 */
44 public void setTarget(Object target){
45 currentAnnotSet = (AnnotationSet) target;
46 }// setTarget();
47
48 /**
49 * Used when the viewer/editor has to display/edit an existing annotation
50 * @param ann the annotation to be displayed or edited. If ann is null then
51 * the method simply returns
52 */
53 public void setAnnotation(Annotation ann){
54 // If ann is null, then simply return.
55 if (ann == null) return;
56 currentAnnot = ann;
57 currentStartOffset = currentAnnot.getStartNode().getOffset();
58 currentEndOffset = currentAnnot.getEndNode().getOffset();
59
60 initLocalData();
61 initGuiComponents();
62
63 }// setAnnotation();
64
65 /**
66 * Used when the viewer has to create new annotations.
67 * @param startOffset the start offset of the span covered by the new
68 * annotation(s). If is <b>null</b> the method will simply return.
69 * @param endOffset the end offset of the span covered by the new
70 * annotation(s). If is <b>null</b> the method will simply return.
71 */
72 public void setSpan(Long startOffset, Long endOffset, String annotationType){
73 // If one of them is null, then simply return.
74 if (startOffset == null || endOffset == null) return;
75
76 currentStartOffset = startOffset;
77 currentEndOffset = endOffset;
78 currentAnnot = null;
79
80 initLocalData();
81 initGuiComponents();
82 }// setSpan();
83
84 /**
85 * Called by the GUI when the user has pressed the "OK" button. This should
86 * trigger the saving of the newly created annotation(s)
87 */
88 public void okAction() throws GateException {
89 if (annotTypeTextField.getText().equals("")){
90 throw new GateException("An annotation type must be specified !");
91 }// End if
92 // This code must be uncomented if the desired behaviour for
93 // UnrestrictedAnnoatationEditor is not to allow annotation types
94 // which have a schema present in the system.
95 /*
96 CreoleRegister creoleReg = Gate.getCreoleRegister();
97 List currentAnnotationSchemaList =
98 creoleReg.getLrInstances("gate.creole.AnnotationSchema");
99 Iterator iter = currentAnnotationSchemaList.iterator();
100 while (iter.hasNext()){
101 AnnotationSchema annotSchema = (AnnotationSchema) iter.next();
102 if (annotTypeTextField.getText().equals(annotSchema.getAnnotationName()))
103 throw new GAteException("There is a schema type for this annotation");
104 }// End while
105 */
106 data.setAnnotType(annotTypeTextField.getText());
107 if (currentAnnot == null){
108 currentAnnotSet.add( currentStartOffset,
109 currentEndOffset,
110 this.getAnnotType(),
111 this.getCurrentAnnotationFeatures());
112 }else{
113 if (currentAnnot.getType().equals(this.getAnnotType())){
114 currentAnnot.setFeatures(this.getCurrentAnnotationFeatures());
115 }else{
116 currentAnnotSet.remove(currentAnnot);
117 currentAnnotSet.add( currentStartOffset,
118 currentEndOffset,
119 this.getAnnotType(),
120 this.getCurrentAnnotationFeatures());
121 }// End if
122 }// End if
123 }//okAction();
124
125
126 public void cancelAction() throws GateException {
127 //no need to do anything, because the editor has not modified anything
128 //on the document or the annotation sets
129 //Had to be added for the tree editor, which does
130 return;
131 }
132
133 /**
134 * Checks whether this viewer/editor can handle a specific annotation type.
135 * @param annotationType represents the annotation type being questioned.If
136 * it is <b>null</b> then the method will return false.
137 * @return true if the SchemaAnnotationEditor can handle the annotationType
138 * or false otherwise.
139 */
140 public boolean canDisplayAnnotationType(String annotationType){
141 return true;
142 }// canDisplayAnnotationType();
143
144 // The Unrestricted Editor functionality
145 // Local data
146
147 /** The curent annotation set used by the editor*/
148 AnnotationSet currentAnnotSet = null;
149 /** The curent annotation used by the editor*/
150 Annotation currentAnnot = null;
151 /** The start offset of the span covered by the currentAnnot*/
152 Long currentStartOffset = null;
153 /** The end offset of the span covered by the currentAnnot*/
154 Long currentEndOffset = null;
155
156 // Local data
157 private MyCustomFeatureBearer data = null;
158
159 // Gui Components
160 JLabel annotTypeLabel = null;
161 JTextField annotTypeTextField = null;
162
163 JLabel featuresLabel = null;
164 FeaturesEditor featuresEditor = null;
165
166 /** Init local data*/
167 protected void initLocalData(){
168 data = new MyCustomFeatureBearer(currentAnnot);
169 }// initLocalData();
170
171 /** Init GUI components with values taken from local data*/
172 protected void initGuiComponents(){
173 this.setLayout(new BoxLayout( this, BoxLayout.Y_AXIS));
174 //create the main box
175 Box componentsBox = Box.createVerticalBox();
176
177 componentsBox.add(Box.createVerticalStrut(10));
178
179 // Add the Annot Type
180 Box box = Box.createVerticalBox();
181 Box box1 = Box.createHorizontalBox();
182 annotTypeLabel = new JLabel("Annotation type");
183 annotTypeLabel.setToolTipText("The type of the annotation you are" +
184 " creating or editing");
185 annotTypeLabel.setOpaque(true);
186
187 box1.add(annotTypeLabel);
188 box1.add(Box.createHorizontalGlue());
189 box.add(box1);
190
191 annotTypeTextField = new JTextField(data.getAnnotType());
192 annotTypeTextField.setColumns(80);
193 annotTypeTextField.setPreferredSize(
194 annotTypeTextField.getPreferredSize());
195 annotTypeTextField.setMinimumSize(
196 annotTypeTextField.getPreferredSize());
197 annotTypeTextField.setMaximumSize(
198 annotTypeTextField.getPreferredSize());
199
200
201 box1 = Box.createHorizontalBox();
202 box1.add(annotTypeTextField);
203 box1.add(Box.createHorizontalGlue());
204 box.add(box1);
205 box.add(Box.createVerticalStrut(10));
206
207 componentsBox.add(box);
208 // add the features editor
209 box = Box.createVerticalBox();
210
211 featuresLabel = new JLabel("Features");
212 featuresLabel.setToolTipText("The features of the annotation you are" +
213 " creating or editing");
214 featuresLabel.setOpaque(true);
215
216 box1 = Box.createHorizontalBox();
217 box1.add(featuresLabel);
218 box1.add(Box.createHorizontalGlue());
219 box.add(box1);
220 box.add(Box.createVerticalStrut(5));
221
222 featuresEditor = new FeaturesEditor();
223 featuresEditor.setFeatureBearer(data);
224
225 box.add(featuresEditor);
226 box.add(Box.createVerticalStrut(10));
227
228 componentsBox.add(box);
229 componentsBox.add(Box.createVerticalStrut(10));
230
231 this.add(componentsBox);
232 this.add(Box.createVerticalStrut(10));
233 }//initGuiComponents()
234
235 /** Init all the listeners*/
236 protected void initListeners(){
237 }//initListeners()
238
239 /** Returns annot type edited with this tool*/
240 public String getAnnotType(){ return data.getAnnotType();}
241
242 /** Returns the features edited with this tool*/
243 protected FeatureMap getCurrentAnnotationFeatures(){ return data.getFeatures();}
244
245 // INNER CLASS
246 /** This class implements a feature bearer. It is used as internal data.
247 * The FeatureEditor will use an object belonging to this class.
248 */
249 class MyCustomFeatureBearer extends AbstractFeatureBearer
250 implements FeatureBearer{
251
252 // Members
253 private FeatureMap features = null;
254 private String annotType = null;
255
256 /** Constructs a custom feature bearer. If annot is null then it creates
257 * empty annotType and fetures.
258 */
259 public MyCustomFeatureBearer(Annotation anAnnot){
260 if (anAnnot != null){
261 features = Factory.newFeatureMap();
262 features.putAll(anAnnot.getFeatures());
263 annotType = new String(anAnnot.getType());
264 }else{
265 features = Factory.newFeatureMap();
266 annotType = new String("");
267 }// End if
268 }//MyCustomFeatureBearer
269
270 // Mutators and accesors
271 public void setFeatures(FeatureMap aFeatureMap){
272 features = aFeatureMap;
273 }// setFeatures();
274
275 public FeatureMap getFeatures(){
276 return features;
277 }// getFeatures()
278
279 public void setAnnotType(String anAnnotType){
280 annotType = anAnnotType;
281 }// setAnnotType();
282
283 public String getAnnotType(){
284 return annotType;
285 }//getAnnotType()
286 }// End class MyCustomFeatureBearer
287 }// End class UnrestrictedAnnotationEditor