1
13 package gate.gui.docview;
14
15 import java.awt.*;
16 import java.awt.Component;
17 import java.awt.Point;
18 import java.awt.event.*;
19 import java.awt.event.ComponentAdapter;
20 import java.awt.event.ComponentEvent;
21 import java.io.IOException;
22 import java.io.Reader;
23 import java.util.*;
24 import java.util.List;
25
26 import javax.swing.*;
27 import javax.swing.Timer;
28 import javax.swing.text.*;
29 import javax.swing.text.Highlighter;
30
31
32 import gate.Annotation;
33 import gate.AnnotationSet;
34 import gate.corpora.DocumentContentImpl;
35 import gate.util.*;
36 import gate.util.GateRuntimeException;
37 import gate.util.RawEditorKit;
38
39
40
43
44 public class TextualDocumentView extends AbstractDocumentView {
45
46 public TextualDocumentView(){
47 blinkingTagsForAnnotations = new HashMap();
48 }
49
50 public Object addHighlight(Annotation ann, AnnotationSet set, Color colour){
51 Highlighter highlighter = textView.getHighlighter();
52 try{
53 Object tag = highlighter.addHighlight(
54 ann.getStartNode().getOffset().intValue(),
55 ann.getEndNode().getOffset().intValue(),
56 new DefaultHighlighter.DefaultHighlightPainter(colour));
57 annotationListView.addAnnotation(tag, ann, set);
58 return tag;
59 }catch(BadLocationException ble){
60 throw new GateRuntimeException(ble.toString());
62 }
63 }
64
65
66 public void scrollAnnotationToVisible(Annotation ann){
67 Rectangle visibleView = scroller.getViewport().getViewRect();
72 int viewStart = textView.viewToModel(visibleView.getLocation());
73 Point endPoint = new Point(visibleView.getLocation());
74 endPoint.translate(visibleView.width, visibleView.height);
75 int viewEnd = textView.viewToModel(endPoint);
76 int annStart = ann.getStartNode().getOffset().intValue();
77 int annEnd = ann.getEndNode().getOffset().intValue();
78 if(annEnd < viewStart || viewEnd < annStart){
79 try{
80 textView.scrollRectToVisible(textView.modelToView(annStart));
81 }catch(BadLocationException ble){
82 throw new GateRuntimeException(ble);
84 }
85 }
86 }
87
88 public void removeHighlight(Object tag){
89 Highlighter highlighter = textView.getHighlighter();
90 highlighter.removeHighlight(tag);
91 annotationListView.removeAnnotation(tag);
92 }
93
94
102 public void moveHighlight(Object tag, int newStart, int newEnd)
103 throws BadLocationException{
104 textView.getHighlighter().changeHighlight(tag, newStart, newEnd);
105 }
106
107
118 public List addHighlights(Collection annotations,
119 AnnotationSet set, Color colour){
120 SwingUtilities.invokeLater(new Runnable(){
122 public void run(){
123 textView.setVisible(false);
124 scroller.getViewport().setView(new JLabel("Updating"));
125 }
126 });
127 while(textView.isVisible())
129 try{
130 Thread.sleep(30);
131 }catch(InterruptedException ie){
132 }
134
135 Highlighter highlighter = textView.getHighlighter();
136
137 Iterator annIter = annotations.iterator();
138 List tagsList = new ArrayList(annotations.size());
139 while(annIter.hasNext()){
140 Annotation ann = (Annotation)annIter.next();
141 try{
142 Object tag = highlighter.addHighlight(
143 ann.getStartNode().getOffset().intValue(),
144 ann.getEndNode().getOffset().intValue(),
145 new DefaultHighlighter.DefaultHighlightPainter(colour));
146 tagsList.add(tag);
147 }catch(BadLocationException ble){
148 throw new GateRuntimeException(ble.toString());
150 }
151 }
152 annotationListView.addAnnotations(tagsList, annotations, set);
153 SwingUtilities.invokeLater(new Runnable(){
154 public void run(){
155 scroller.getViewport().setView(textView);
156 textView.setVisible(true);
157 }
158 });
159 return tagsList;
160 }
161
162
167 public void removeHighlights(Collection tags){
168 SwingUtilities.invokeLater(new Runnable(){
170 public void run(){
171 textView.setVisible(false);
172 scroller.getViewport().setView(new JLabel("Updating"));
173 }
174 });
175 while(textView.isVisible())
177 try{
178 Thread.sleep(30);
179 }catch(InterruptedException ie){
180 }
182
183 Highlighter highlighter = textView.getHighlighter();
184
185 Iterator tagIter = tags.iterator();
186 while(tagIter.hasNext()){
187 highlighter.removeHighlight(tagIter.next());
188 }
189 annotationListView.removeAnnotations(tags);
190 SwingUtilities.invokeLater(new Runnable(){
191 public void run(){
192 scroller.getViewport().setView(textView);
193 textView.setVisible(true);
194 }
195 });
196 }
197
198
199 public void addBlinkingHighlight(Annotation ann){
200 synchronized(blinkingTagsForAnnotations){
201 blinkingTagsForAnnotations.put(ann.getId(), new AnnotationTag(ann, null));
202 }
203 }
204
205 public void removeBlinkingHighlight(Annotation ann){
206 synchronized(blinkingTagsForAnnotations){
207 AnnotationTag annTag = (AnnotationTag)blinkingTagsForAnnotations.
208 remove(ann.getId());
209 if(annTag != null && annTag.getTag() != null)
210 textView.getHighlighter().removeHighlight(annTag.getTag());
211 }
212 }
213
214
215 public void removeAllBlinkingHighlights(){
216 synchronized(blinkingTagsForAnnotations){
217 Iterator annIdIter = new ArrayList(blinkingTagsForAnnotations.keySet()).
218 iterator();
219 while(annIdIter.hasNext()){
220 AnnotationTag annTag = (AnnotationTag)
221 blinkingTagsForAnnotations.remove(annIdIter.next());
222 Annotation ann = annTag.getAnnotation();
223 Object tag = annTag.getTag();
224 if(tag != null){
225 Highlighter highlighter = textView.getHighlighter();
226 highlighter.removeHighlight(tag);
227 }
228 }
229 }
230 }
231
232
233 public int getType() {
234 return CENTRAL;
235 }
236
237
238
239
242 protected void initGUI() {
243 textView = new JEditorPane();
244 textView.setContentType("text/plain");
245 textView.setEditorKit(new RawEditorKit());
246 textView.setAutoscrolls(false);
247 scroller = new JScrollPane(textView);
248
249 textView.setText(document.getContent().toString());
250 textView.getDocument().addDocumentListener(new SwingDocumentListener());
251 scroller.getViewport().setViewPosition(new Point(0, 0));
252
253 Iterator horizViewsIter = owner.getHorizontalViews().iterator();
256 while(annotationListView == null && horizViewsIter.hasNext()){
257 DocumentView aView = (DocumentView)horizViewsIter.next();
258 if(aView instanceof AnnotationListView)
259 annotationListView = (AnnotationListView)aView;
260 }
261 blinker = new Timer(BLINK_DELAY, new BlinkAction());
262 blinker.setRepeats(true);
263 blinker.start();
264 initListeners();
265 }
266
267 public Component getGUI(){
268 return scroller;
269 }
270
271 protected void initListeners(){
272 textView.addComponentListener(new ComponentAdapter(){
273 public void componentResized(ComponentEvent e){
274 try{
275 scroller.getViewport().setViewPosition(
276 textView.modelToView(0).getLocation());
277 scroller.paintImmediately(textView.getBounds());
278 }catch(BadLocationException ble){
279 }
281 }
282 });
283 }
284 protected void unregisterHooks(){}
285 protected void registerHooks(){}
286
287
288
291 protected class BlinkAction extends AbstractAction{
292 public void actionPerformed(ActionEvent evt){
293 synchronized(blinkingTagsForAnnotations){
295 if(blinkingTagsForAnnotations.isEmpty()) return;
297 Iterator annIdIter = new ArrayList(blinkingTagsForAnnotations.keySet()).
298 iterator();
299 Highlighter highlighter = textView.getHighlighter();
300 if(highlightsShown){
301 while(annIdIter.hasNext()){
303 AnnotationTag annTag = (AnnotationTag)
304 blinkingTagsForAnnotations.get(annIdIter.next());
305 Annotation ann = annTag.getAnnotation();
306 Object tag = annTag.getTag();
307 if(tag != null) highlighter.removeHighlight(tag);
308 annTag.setTag(null);
309 }
310 highlightsShown = false;
311 }else{
312 while(annIdIter.hasNext()){
314 AnnotationTag annTag = (AnnotationTag)
315 blinkingTagsForAnnotations.get(annIdIter.next());
316 Annotation ann = annTag.getAnnotation();
317 try{
318 Object tag = highlighter.addHighlight(
319 ann.getStartNode().getOffset().intValue(),
320 ann.getEndNode().getOffset().intValue(),
321 new DefaultHighlighter.DefaultHighlightPainter(
322 textView.getSelectionColor()));
323 annTag.setTag(tag);
324 }catch(BadLocationException ble){
326 throw new GateRuntimeException(ble);
328 }
329 }
330 highlightsShown = true;
331 }
332 }
333 }
334 protected boolean highlightsShown = false;
335 }
336
337 class SwingDocumentListener implements javax.swing.event.DocumentListener{
338 public void insertUpdate(final javax.swing.event.DocumentEvent e) {
339 try{
341 document.edit(new Long(e.getOffset()), new Long(e.getOffset()),
342 new DocumentContentImpl(
343 e.getDocument().getText(e.getOffset(), e.getLength())));
344 }catch(BadLocationException ble){
345 ble.printStackTrace(Err.getPrintWriter());
346 }catch(InvalidOffsetException ioe){
347 ioe.printStackTrace(Err.getPrintWriter());
348 }
349 Component listView = annotationListView.getGUI();
351 if(listView != null) listView.repaint();
352 }
353
354 public void removeUpdate(final javax.swing.event.DocumentEvent e) {
355 try{
357 document.edit(new Long(e.getOffset()),
358 new Long(e.getOffset() + e.getLength()),
359 new DocumentContentImpl(""));
360 }catch(InvalidOffsetException ioe){
361 ioe.printStackTrace(Err.getPrintWriter());
362 }
363 Component listView = annotationListView.getGUI();
365 if(listView != null) listView.repaint();
366 }
367
368 public void changedUpdate(javax.swing.event.DocumentEvent e) {
369 }
371 }
373
376 class AnnotationTag{
377
378
381 public void setTag(Object tag){
382 this.tag = tag;
383 }
384 public AnnotationTag(Annotation annotation, Object tag){
385 this.annotation = annotation;
386 this.tag = tag;
387 }
388
389
392 public Annotation getAnnotation(){
393 return annotation;
394 }
395
398 public Object getTag(){
399 return tag;
400 }
401 Annotation annotation;
402 Object tag;
403 }
404
405 protected JScrollPane scroller;
406 protected AnnotationListView annotationListView;
407
408
412 protected Map blinkingTagsForAnnotations;
413
414 protected Timer blinker;
415
416 protected JEditorPane textView;
417
418
421 protected final static int BLINK_DELAY = 400;
422 }
423