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 public void removeHighlight(Object tag){
66 Highlighter highlighter = textView.getHighlighter();
67 highlighter.removeHighlight(tag);
68 annotationListView.removeAnnotation(tag);
69 }
70
71
79 public void moveHighlight(Object tag, int newStart, int newEnd)
80 throws BadLocationException{
81 textView.getHighlighter().changeHighlight(tag, newStart, newEnd);
82 }
83
84
95 public List addHighlights(Collection annotations,
96 AnnotationSet set, Color colour){
97 SwingUtilities.invokeLater(new Runnable(){
99 public void run(){
100 textView.setVisible(false);
101 scroller.getViewport().setView(new JLabel("Updating"));
102 }
103 });
104 while(textView.isVisible())
106 try{
107 Thread.sleep(30);
108 }catch(InterruptedException ie){
109 }
111
112 Highlighter highlighter = textView.getHighlighter();
113
114 Iterator annIter = annotations.iterator();
115 List tagsList = new ArrayList(annotations.size());
116 while(annIter.hasNext()){
117 Annotation ann = (Annotation)annIter.next();
118 try{
119 Object tag = highlighter.addHighlight(
120 ann.getStartNode().getOffset().intValue(),
121 ann.getEndNode().getOffset().intValue(),
122 new DefaultHighlighter.DefaultHighlightPainter(colour));
123 tagsList.add(tag);
124 }catch(BadLocationException ble){
125 throw new GateRuntimeException(ble.toString());
127 }
128 }
129 annotationListView.addAnnotations(tagsList, annotations, set);
130 SwingUtilities.invokeLater(new Runnable(){
131 public void run(){
132 scroller.getViewport().setView(textView);
133 textView.setVisible(true);
134 }
135 });
136 return tagsList;
137 }
138
139
144 public void removeHighlights(Collection tags){
145 SwingUtilities.invokeLater(new Runnable(){
147 public void run(){
148 textView.setVisible(false);
149 scroller.getViewport().setView(new JLabel("Updating"));
150 }
151 });
152 while(textView.isVisible())
154 try{
155 Thread.sleep(30);
156 }catch(InterruptedException ie){
157 }
159
160 Highlighter highlighter = textView.getHighlighter();
161
162 Iterator tagIter = tags.iterator();
163 while(tagIter.hasNext()){
164 highlighter.removeHighlight(tagIter.next());
165 }
166 annotationListView.removeAnnotations(tags);
167 SwingUtilities.invokeLater(new Runnable(){
168 public void run(){
169 scroller.getViewport().setView(textView);
170 textView.setVisible(true);
171 }
172 });
173 }
174
175
176 public void addBlinkingHighlight(Annotation ann){
177 synchronized(blinkingTagsForAnnotations){
178 blinkingTagsForAnnotations.put(ann.getId(), new AnnotationTag(ann, null));
179 }
180 }
181
182 public void removeBlinkingHighlight(Annotation ann){
183 synchronized(blinkingTagsForAnnotations){
184 AnnotationTag annTag = (AnnotationTag)blinkingTagsForAnnotations.
185 remove(ann.getId());
186 if(annTag != null && annTag.getTag() != null)
187 textView.getHighlighter().removeHighlight(annTag.getTag());
188 }
189 }
190
191 public void removeAllBlinkingHighlights(){
192 synchronized(blinkingTagsForAnnotations){
193 Iterator annIdIter = new ArrayList(blinkingTagsForAnnotations.keySet()).
194 iterator();
195 while(annIdIter.hasNext()){
196 AnnotationTag annTag = (AnnotationTag)
197 blinkingTagsForAnnotations.remove(annIdIter.next());
198 Annotation ann = annTag.getAnnotation();
199 Object tag = annTag.getTag();
200 if(tag != null){
201 Highlighter highlighter = textView.getHighlighter();
202 highlighter.removeHighlight(tag);
203 }
204 }
205 }
206 }
207
208
209 public int getType() {
210 return CENTRAL;
211 }
212
213
214
215
218 protected void initGUI() {
219 textView = new JEditorPane();
220 textView.setContentType("text/plain");
221 textView.setEditorKit(new RawEditorKit());
222 textView.setAutoscrolls(false);
223 scroller = new JScrollPane(textView);
224
225 textView.setText(document.getContent().toString());
226 textView.getDocument().addDocumentListener(new SwingDocumentListener());
227 scroller.getViewport().setViewPosition(new Point(0, 0));
228
229 Iterator horizViewsIter = owner.getHorizontalViews().iterator();
232 while(annotationListView == null && horizViewsIter.hasNext()){
233 DocumentView aView = (DocumentView)horizViewsIter.next();
234 if(aView instanceof AnnotationListView)
235 annotationListView = (AnnotationListView)aView;
236 }
237 blinker = new Timer(BLINK_DELAY, new BlinkAction());
238 blinker.setRepeats(true);
239 blinker.start();
240 initListeners();
241 }
242
243 public Component getGUI(){
244 return scroller;
245 }
246
247 protected void initListeners(){
248 textView.addComponentListener(new ComponentAdapter(){
249 public void componentResized(ComponentEvent e){
250 try{
251 scroller.getViewport().setViewPosition(
252 textView.modelToView(0).getLocation());
253 scroller.paintImmediately(textView.getBounds());
254 }catch(BadLocationException ble){
255 }
257 }
258 });
259 }
260 protected void unregisterHooks(){}
261 protected void registerHooks(){}
262
263
264
267 protected class BlinkAction extends AbstractAction{
268 public void actionPerformed(ActionEvent evt){
269 synchronized(blinkingTagsForAnnotations){
271 if(blinkingTagsForAnnotations.isEmpty()) return;
273 Iterator annIdIter = new ArrayList(blinkingTagsForAnnotations.keySet()).
274 iterator();
275 Highlighter highlighter = textView.getHighlighter();
276 if(highlightsShown){
277 while(annIdIter.hasNext()){
279 AnnotationTag annTag = (AnnotationTag)
280 blinkingTagsForAnnotations.get(annIdIter.next());
281 Annotation ann = annTag.getAnnotation();
282 Object tag = annTag.getTag();
283 if(tag != null) highlighter.removeHighlight(tag);
284 annTag.setTag(null);
285 }
286 highlightsShown = false;
287 }else{
288 while(annIdIter.hasNext()){
290 AnnotationTag annTag = (AnnotationTag)
291 blinkingTagsForAnnotations.get(annIdIter.next());
292 Annotation ann = annTag.getAnnotation();
293 try{
294 Object tag = highlighter.addHighlight(
295 ann.getStartNode().getOffset().intValue(),
296 ann.getEndNode().getOffset().intValue(),
297 new DefaultHighlighter.DefaultHighlightPainter(
298 textView.getSelectionColor()));
299 annTag.setTag(tag);
300 textView.scrollRectToVisible(textView.
301 modelToView(ann.getStartNode().getOffset().intValue()));
302 }catch(BadLocationException ble){
303 throw new GateRuntimeException(ble);
305 }
306 }
307 highlightsShown = true;
308 }
309 }
310 }
311 protected boolean highlightsShown = false;
312 }
313
314 class SwingDocumentListener implements javax.swing.event.DocumentListener{
315 public void insertUpdate(final javax.swing.event.DocumentEvent e) {
316 try{
318 document.edit(new Long(e.getOffset()), new Long(e.getOffset()),
319 new DocumentContentImpl(
320 e.getDocument().getText(e.getOffset(), e.getLength())));
321 }catch(BadLocationException ble){
322 ble.printStackTrace(Err.getPrintWriter());
323 }catch(InvalidOffsetException ioe){
324 ioe.printStackTrace(Err.getPrintWriter());
325 }
326 Component listView = annotationListView.getGUI();
328 if(listView != null) listView.repaint();
329 }
330
331 public void removeUpdate(final javax.swing.event.DocumentEvent e) {
332 try{
334 document.edit(new Long(e.getOffset()),
335 new Long(e.getOffset() + e.getLength()),
336 new DocumentContentImpl(""));
337 }catch(InvalidOffsetException ioe){
338 ioe.printStackTrace(Err.getPrintWriter());
339 }
340 annotationListView.getGUI().repaint();
342 }
343
344 public void changedUpdate(javax.swing.event.DocumentEvent e) {
345 }
347 }
349
352 class AnnotationTag{
353
354
357 public void setTag(Object tag){
358 this.tag = tag;
359 }
360 public AnnotationTag(Annotation annotation, Object tag){
361 this.annotation = annotation;
362 this.tag = tag;
363 }
364
365
368 public Annotation getAnnotation(){
369 return annotation;
370 }
371
374 public Object getTag(){
375 return tag;
376 }
377 Annotation annotation;
378 Object tag;
379 }
380
381 protected JScrollPane scroller;
382 protected AnnotationListView annotationListView;
383
384
388 protected Map blinkingTagsForAnnotations;
389
390 protected Timer blinker;
391
392 protected JEditorPane textView;
393
394
397 protected final static int BLINK_DELAY = 400;
398 }
399