|
STreeNode |
|
1 /* 2 * STreeNode.java 3 * 4 * Copyright (c) 1998-2001, The University of Sheffield. 5 * 6 * This file is part of GATE (see http://gate.ac.uk/), and is free 7 * software, licenced under the GNU Library General Public License, 8 * Version 2, June 1991 (in the distribution as file licence.html, 9 * and also available at http://gate.ac.uk/gate/licence.html). 10 * 11 * Kalina Bontcheva, 07/08/2001 12 * 13 * $Id: STreeNode.java,v 1.11 2003/01/28 10:01:16 marin Exp $ 14 */ 15 16 package gate.gui; 17 18 import javax.swing.tree.*; 19 20 import java.awt.Rectangle; 21 22 import java.util.*; 23 24 25 import gate.*; 26 import gate.util.*; 27 28 29 public class STreeNode extends DefaultMutableTreeNode { 30 31 /** Debug flag */ 32 private static final boolean DEBUG = false; 33 private static final String ADDEDSET = "TreeViewerTempAdded"; 34 private static final String REMOVEDSET = "TreeViewerTempRemoved"; 35 36 static int nextID = 0; 37 38 int level; // level in the syntax tree 39 int nodeID; //ID of the node 40 41 long start, end; //the start and end nodes for this annotation 42 Annotation annot; //the annotation that's created during import/export 43 //not to be used otherwise. During import span is set to 44 //be the same as the annotation span. During export the 45 //annotation span is set to be the same as the span. 46 47 public STreeNode(Annotation annot) { 48 level = -1; 49 nodeID = nextID++; 50 //span = annot.getSpans().getElementAt(0); 51 //get the first span, there should be no others 52 this.annot = annot; 53 this.start = annot.getStartNode().getOffset().longValue(); 54 this.end = annot.getEndNode().getOffset().longValue(); 55 }// public STreeNode(Annotation annot) 56 57 public STreeNode(long start, long end) { 58 level = -1; 59 nodeID = nextID++; 60 this.start = start; 61 this.end = end; 62 }// public STreeNode(int start, int end) 63 64 public STreeNode() { 65 level = -1; 66 nodeID = nextID++; 67 start = 0; 68 end = 0; 69 }// public STreeNode() 70 71 public int getLevel() { 72 return level; 73 }// public int getLevel() 74 75 public void setLevel(long level) { 76 this.level = (int) level; 77 }// public void setLevel(int level) 78 79 public void setLevel(int level) { 80 this.level = level; 81 }// public void setLevel(int level) 82 83 public int getID() { 84 return nodeID; 85 }// public int getID() 86 87 public long getStart() { 88 return start; 89 }// public int getStart() 90 91 public void setStart(long start) { 92 this.start = start; 93 }// public void setStart(int start) 94 95 public long getEnd() { 96 return end; 97 }// public int getEnd() 98 99 public void setEnd(long end) { 100 this.end = end; 101 }// public void setEnd(int end) 102 103 /** 104 * This also sets the span to match the annotation span! 105 */ 106 public void setAnnotation(Annotation annot) { 107 this.annot = annot; 108 this.start = annot.getStartNode().getOffset().longValue(); 109 this.end = annot.getEndNode().getOffset().longValue(); 110 }// public void setAnnotation(Annotation annot) 111 112 public Annotation getAnnotation() { 113 return annot; 114 }// public Annotation getAnnotation() 115 116 public void disconnectChildren() { 117 for (Iterator i = this.children.iterator(); i.hasNext(); ) 118 ((STreeNode) i.next()).setParent(null); 119 this.children.clear(); 120 }// public void disconnectChildren() 121 122 /** 123 * Creates an annotation of the given type. If the children don't have their 124 * annotation objects created, it creates them and assigns the pointers. 125 * Expects the text string relative to which all offsets were created! 126 */ 127 public boolean createAnnotation(Document doc, String type, 128 String text, long utteranceOffset) { 129 boolean created = false; 130 131 if (annot != null ) 132 return false; 133 134 //no document, so cannot add annotations 135 if (doc == null) 136 return false; 137 138 // check if it has children. If it hasn't then it shouldn't have an 139 // annotation because all our leaf nodes are actually just words 140 // from the text (e.g. "this", "that"). Their categories are always 141 // encoded as non-terminal nodes. 142 if ( ! this.getAllowsChildren()) 143 return false; 144 145 FeatureMap attribs = Factory.newFeatureMap(); 146 // the text spanned by the annotation is stored as the userObject of the 147 // tree node 148 // comes from the default Swing tree node 149 List consists = new ArrayList(); 150 151 Long lStart = new Long(start), lEnd = new Long(end); 152 // try { 153 // attribs.put("text", 154 // doc.getContent().getContent(lStart, lEnd).toString()); 155 // } catch (InvalidOffsetException ex) { 156 // throw new RuntimeException(ex.getMessage()); 157 // } 158 attribs.put("text", 159 text.substring( (int) (start - utteranceOffset), 160 (int) (end - utteranceOffset) ) 161 ); 162 attribs.put("cat", (String) this.getUserObject()); 163 attribs.put("consists", consists); 164 165 // children comes from DefaultMutableTreeNode 166 for (Iterator i = children.iterator(); i.hasNext(); ) { 167 STreeNode child = (STreeNode) i.next(); 168 if (child.getAnnotation() == null) { 169 if (child.getAllowsChildren()) 170 if (createAnnotation(doc, type, text, utteranceOffset)) 171 consists.add(child.getAnnotation().getId()); 172 } else 173 consists.add(child.getAnnotation().getId()); 174 } 175 176 //!!! Need to account for the name of the Annot Set 177 AnnotationSet theSet = doc.getAnnotations(ADDEDSET); 178 try { 179 Integer Id = theSet.add(lStart, lEnd, type, attribs); 180 this.annot = theSet.get(Id); 181 created = true; 182 } catch (InvalidOffsetException ex) { 183 Out.println("Invalid annotation offsets: " 184 + start + " and/or " + end); 185 created = false; 186 } 187 188 return created; 189 }// public boolean createAnnotation 190 191 192 /** 193 * Transfers the annotations from added to the given annotation set 194 * Also, for each annotation in removed, removes it from the given annotation set 195 * Called by OkAction() in the treeViewer to finalise the changes. 196 */ 197 public static boolean transferAnnotations(Document doc, AnnotationSet targetAS) { 198 if (doc == null || targetAS == null) 199 return false; 200 201 HashMap tempId2permId = new HashMap(); 202 List newAnnots = new ArrayList(); 203 AnnotationSet addedSet = doc.getAnnotations(ADDEDSET); 204 if (addedSet != null && !addedSet.isEmpty()) { 205 Iterator addedIter = addedSet.iterator(); 206 while (addedIter.hasNext()) { 207 Annotation annot = (Annotation) addedIter.next(); 208 try { 209 Integer permId = 210 targetAS.add(annot.getStartNode().getOffset(), 211 annot.getEndNode().getOffset(), 212 annot.getType(), 213 annot.getFeatures()); 214 tempId2permId.put(annot.getId(), permId); 215 newAnnots.add(targetAS.get(permId)); 216 } catch (InvalidOffsetException ex) { 217 Out.println("Invalid annotation offsets: " 218 + annot.getStartNode().getOffset() 219 + " and/or " + annot.getEndNode().getOffset()); 220 } 221 }//while 222 223 //now update the consists Ids, because they have the old Ids in them 224 for (int i=0; i < newAnnots.size(); i++) { 225 Annotation newAnnot = (Annotation) newAnnots.get(i); 226 List children = (List) newAnnot.getFeatures().get( 227 SyntaxTreeViewer.NODE_CONSISTS_FEATURE_NAME); 228 if (children == null || children.size()== 0) { 229 continue; 230 } 231 else { 232 List newList = new ArrayList(); 233 for (int k=0; k< children.size(); k++) { 234 Integer oldId = (Integer) children.get(k); 235 if (tempId2permId.get(oldId) != null) 236 newList.add(tempId2permId.get(oldId)); 237 else 238 newList.add(oldId); 239 } 240 newAnnot.getFeatures().put(SyntaxTreeViewer.NODE_CONSISTS_FEATURE_NAME, 241 newList); 242 } 243 }//for 244 245 addedSet.clear(); 246 247 } 248 doc.removeAnnotationSet(ADDEDSET); 249 250 251 AnnotationSet removedSet = doc.getAnnotations(REMOVEDSET); 252 if (removedSet != null && ! removedSet.isEmpty()) { 253 targetAS.removeAll(removedSet); 254 removedSet.clear(); 255 } 256 doc.removeAnnotationSet(REMOVEDSET); 257 258 return true; 259 } 260 261 public static void undo(Document doc) { 262 AnnotationSet addedSet = doc.getAnnotations(ADDEDSET); 263 AnnotationSet removedSet = doc.getAnnotations(REMOVEDSET); 264 addedSet.clear(); 265 removedSet.clear(); 266 doc.removeAnnotationSet(ADDEDSET); 267 doc.removeAnnotationSet(REMOVEDSET); 268 } 269 270 /** Store the annotation in the deleted list so it can retrieved later */ 271 public void removeAnnotation(Document doc) { 272 if (this.annot == null || doc == null) 273 return; 274 275 doc.getAnnotations(REMOVEDSET).add(this.annot); 276 277 this.annot = null; 278 }// public void removeAnnotation(Document doc) 279 280 } // STreeNode 281 282 // $Log: STreeNode.java,v $ 283 // Revision 1.11 2003/01/28 10:01:16 marin 284 // [marin] bugfixes from Kali 285 // 286 // Revision 1.10 2001/12/03 14:04:04 kalina 287 // code cleanup in STreeNode.java 288 // 289 // Revision 1.9 2001/08/07 19:03:05 kalina 290 // Made the tree viewer use Token annotations to break the sentence for annotation 291 // 292 // Revision 1.8 2001/08/07 17:01:32 kalina 293 // Changed the AVR implementing classes in line with the updated AVR 294 // API (cancelAction() and setSpan new parameter). 295 // 296 // Also updated the TreeViewer, so now it can be used to edit and view 297 // Sentence annotations and the SyntaxTreeNodes associated with them. 298 // So if you have trees, it'll show them, if not, it'll help you build them. 299 // 300 // Revision 1.7 2001/04/09 10:36:36 oana 301 // a few changes in the code style 302 // 303 // Revision 1.6 2000/11/08 16:35:00 hamish 304 // formatting 305 // 306 // Revision 1.5 2000/10/26 10:45:25 oana 307 // Modified in the code style 308 // 309 // Revision 1.4 2000/10/18 13:26:47 hamish 310 // Factory.createResource now working, with a utility method that uses 311 // reflection (via java.beans.Introspector) to set properties on a resource 312 // from the 313 // parameter list fed to createResource. 314 // resources may now have both an interface and a class; they are indexed 315 // by interface type; the class is used to instantiate them 316 // moved createResource from CR to Factory 317 // removed Transients; use Factory instead 318 // 319 // Revision 1.3 2000/10/16 16:44:32 oana 320 // Changed the comment of DEBUG variable 321 // 322 // Revision 1.2 2000/10/10 15:36:34 oana 323 // Changed System.out in Out and System.err in Err; 324 // Added the DEBUG variable seted on false; 325 // Added in the header the licence; 326 // 327 // Revision 1.1 2000/09/20 17:03:37 kalina 328 // Added the tree viewer from the prototype. It works now with the new 329 // annotation API. 330 // 331 // Revision 1.6 1999/08/23 14:13:38 kalina 332 // Fixed resizing bugs in tree viewers 333 // 334 // Revision 1.5 1999/08/20 21:11:56 kalina 335 // Fixed most bugs and TreeViewer can now import and export annotations 336 // correctly 337 // There is still a delete bug somewhere. 338 // 339 // Revision 1.4 1999/08/18 17:55:24 kalina 340 // Added annotation export for the TreeViewer. Annotation import is the only 341 // thing that remains. 342 // 343 // Revision 1.3 1999/08/13 17:56:31 kalina 344 // Fixed the annotation of nodes in the TreeViewer to be done with click 345 // 346 // Revision 1.2 1999/08/12 16:10:12 kalina 347 // Added a new tree stereotype. Not in final version but would do for testing. 348 // 349 // Improved the tree viewer to allow dynamic creation of all nodes. 350 // Now I can build many trees or one tree; can delete non-terminal nodes; 351 // select/unselect nodes for annotation 352 // Overlapping trees are not a big problem too :-) Not wonderfully drawn but 353 // would do. 354 // 355 // Revision 1.1 1999/08/09 18:00:53 kalina 356 // Made the tree viewer to display an utterance/sentence annotation to start annotating them 357 // 358
|
STreeNode |
|