1
14 package gate.gui;
15
16 import java.awt.*;
17 import java.awt.event.*;
18 import java.awt.font.TextAttribute;
19 import java.awt.print.*;
20 import java.beans.*;
21 import java.io.IOException;
22 import java.io.Reader;
23 import java.util.*;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26 import javax.swing.*;
27 import javax.swing.border.Border;
28 import javax.swing.event.ListSelectionEvent;
29 import javax.swing.event.ListSelectionListener;
30 import javax.swing.table.AbstractTableModel;
31 import javax.swing.text.*;
32 import javax.swing.tree.*;
33 import gate.*;
34 import gate.corpora.DocumentContentImpl;
35 import gate.creole.*;
36 import gate.event.*;
37 import gate.print.JComponentPrinter;
38 import gate.swing.*;
39 import gate.util.*;
40
41
51 public class DocumentEditor extends AbstractVisualResource
52 implements ANNIEConstants{
53 private transient PropertyChangeSupport propertyChangeListeners =
55 new PropertyChangeSupport(this);
56
59 private gate.Document document;
60
61
65 protected ColorGenerator colGenerator = new ColorGenerator();
66
67
69 protected JTextPane textPane;
70
71
72 protected JScrollPane textScroll;
73
74
75 protected XJTable annotationsTable;
76
77
78 protected AnnotationsTableModel annotationsTableModel;
79
80
81 protected JScrollPane tableScroll;
82
83
84 protected JSplitPane leftSplit;
85
86
89 protected JSplitPane rightSplit;
90
91
94 protected JSplitPane mainSplit;
95
96
100 protected JTree stylesTree;
101
102
105 protected JToolBar toolbar;
106
107
108 protected JScrollPane stylesTreeScroll;
109
110
111 protected DefaultMutableTreeNode stylesTreeRoot;
112
113
114 protected DefaultTreeModel stylesTreeModel;
115
116
117 protected SearchDialog searchDialog;
118
119
120 protected TextAttributesChooser styleChooser;
121
122
123
126 protected JTree corefTree;
127
130 protected DefaultMutableTreeNode corefTreeRoot;
131
132
135 protected DefaultTreeModel corefTreeModel;
136
137
138 protected JScrollPane corefScroll;
139
140
144 protected Box progressBox;
145
146
147 protected JProgressBar progressBar;
148
149
154 protected Highlighter highlighter;
155
156
162 protected Highlighter selectionHighlighter;
163
164
167 protected SelectionBlinker selectionBlinker;
168
169
170 protected Handle myHandle;
171
172
175 protected java.util.List data;
176
177
183 protected java.util.List ranges;
184
185
191 protected Map typeDataMap;
192
193
197 protected EventsHandler eventHandler;
198
199
200
204 protected Object lock;
205
206
207
208
209
210
215
216
217 private boolean editable = true;
218
219
220
221 private JToggleButton textVisibleBtn;
222 private JToggleButton typesTreeVisibleBtn;
223 private JToggleButton annotationsTableVisibleBtn;
224 private JToggleButton coreferenceVisibleBtn;
225 private boolean annotationsTableVisible = false;
226 private boolean coreferenceVisible = false;
227 private boolean textVisible = true;
228 private boolean typesTreeVisible = false;
229 private boolean corefOptionAvailable = false;
230
231
235 public DocumentEditor() {
236 }
237
238 public Resource init(){
239 initLocalData();
240 initGuiComponents();
241 initListeners();
242 return this;
243 }
244
245
249 protected void initListeners() {
250 this.addPropertyChangeListener(new PropertyChangeListener() {
252 public void propertyChange(PropertyChangeEvent e) {
253 if(e.getPropertyName().equals("annotationsTableVisible") ||
254 e.getPropertyName().equals("coreferenceVisible") ||
255 e.getPropertyName().equals("textVisible") ||
256 e.getPropertyName().equals("typesTreeVisible")){
257 layoutComponents();
258 }else if(e.getPropertyName().equals("corefOptionAvailable")){
259 if(((Boolean)e.getNewValue()).booleanValue()){
260 if(toolbar.getComponentIndex(coreferenceVisibleBtn) == -1)
261 toolbar.add(coreferenceVisibleBtn, 3);
262 }else{
263 toolbar.remove(coreferenceVisibleBtn);
264 }
265 layoutComponents();
266 }
267 }
268 });
269
270 textVisibleBtn.addActionListener(new ActionListener() {
271 public void actionPerformed(ActionEvent e) {
272 setTextVisible(textVisibleBtn.isSelected());
273 }
274 });
275
276 annotationsTableVisibleBtn.addActionListener(new ActionListener() {
277 public void actionPerformed(ActionEvent e) {
278 setAnnotationsTableVisible(annotationsTableVisibleBtn.isSelected());
279 }
280 });
281
282
283 typesTreeVisibleBtn.addActionListener(new ActionListener() {
284 public void actionPerformed(ActionEvent e) {
285 setTypesTreeVisible(typesTreeVisibleBtn.isSelected());
286 }
287 });
288
289
290 coreferenceVisibleBtn.addActionListener(new ActionListener() {
291 public void actionPerformed(ActionEvent e) {
292 setCoreferenceVisible(coreferenceVisibleBtn.isSelected());
293 }
294 });
295
296 stylesTree.addMouseListener(new MouseAdapter() {
297 public void mouseClicked(MouseEvent e) {
298 if(SwingUtilities.isLeftMouseButton(e)){
299 int x = e.getX();
301 int y = e.getY();
302 TreePath path = stylesTree.getPathForLocation(x, y);
303 if(path != null){
304 DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.
305 getLastPathComponent();
306 TypeData nData = (TypeData)node.getUserObject();
307 Rectangle cellRect = stylesTree.getPathBounds(path);
309 x -= cellRect.x;
310 y -= cellRect.y;
311 Component cellComp = stylesTree.getCellRenderer().
312 getTreeCellRendererComponent(stylesTree,
313 node, true,
314 false, false,
315 0, true);
316 cellComp.setBounds(cellRect);
318 Component clickedComp = cellComp.getComponentAt(x, y);
319
320 if(clickedComp instanceof JCheckBox){
321 nData.setVisible(! nData.getVisible());
322 stylesTreeModel.nodeChanged(node);
324 }else if( e.getClickCount() == 1 &&
326 clickedComp instanceof JLabel &&
327 isTextSelected()){
328
331 if(!editable) return;
332 Long startOffset = new Long(textPane.getSelectionStart());
333 Long endOffset = new Long(textPane.getSelectionEnd());
334 TreePath treePath = stylesTree.getSelectionPath();
335 TypeData typeData = (TypeData)((DefaultMutableTreeNode)
336 treePath.getLastPathComponent()).getUserObject();
337 String setName = typeData.getSet();
338 if(typeData.getType() == null){
339 textPane.setSelectionStart(startOffset.intValue());
342 textPane.setSelectionEnd(startOffset.intValue());
343 return;
344 } try{
346 if ("Default".equals(setName)){
347 document.getAnnotations().add(startOffset,
348 endOffset,
349 typeData.getType(),
350 Factory.newFeatureMap());
351 }else{
352 document.getAnnotations(setName).add( startOffset,
353 endOffset,
354 typeData.getType(),
355 Factory.newFeatureMap());
356 } } catch(gate.util.InvalidOffsetException ioe){
358 throw new GateRuntimeException(ioe.getMessage());
359 } textPane.setSelectionStart(startOffset.intValue());
362 textPane.setSelectionEnd(startOffset.intValue());
363 }else if(clickedComp instanceof JLabel &&
364 e.getClickCount() == 2){
365 if(styleChooser == null){
366 Window parent = SwingUtilities.getWindowAncestor(
367 DocumentEditor.this);
368 styleChooser = parent instanceof Frame ?
369 new TextAttributesChooser((Frame)parent,
370 "Please select your options",
371 true) :
372 new TextAttributesChooser((Dialog)parent,
373 "Please select your options",
374 true);
375
376 }
377
378 styleChooser.setLocationRelativeTo(stylesTree);
379 nData.setAttributes(
380 styleChooser.show(nData.getAttributes().copyAttributes()));
381 stylesTreeModel.nodeChanged(node);
382 }
384 }
385 }
386 }
387 });
388
389 stylesTree.addComponentListener(new ComponentAdapter() {
390 public void componentHidden(ComponentEvent e) {
391
392 }
393
394 public void componentMoved(ComponentEvent e) {
395 }
396
397 public void componentResized(ComponentEvent e) {
398 SwingUtilities.invokeLater(new Runnable(){
399 public void run(){
400 Enumeration nodes = stylesTreeRoot.depthFirstEnumeration();
401 while(nodes.hasMoreElements()){
402 stylesTreeModel.nodeChanged((TreeNode)nodes.nextElement());
403 }
404 }
405 });
406 }
407
408 public void componentShown(ComponentEvent e) {
409 }
410 });
411
412 tableScroll.addMouseListener(new MouseAdapter() {
414 public void mouseClicked(MouseEvent e) {
415 Point location = e.getPoint();
416 if(!tableScroll.getViewport().getView().getBounds().contains(location)){
417 annotationsTable.clearSelection();
419 }
420 }
421 });
422
423 annotationsTable.addMouseListener(new MouseAdapter() {
424 public void mouseClicked(MouseEvent e) {
425 int row = annotationsTable.rowAtPoint(e.getPoint());
426 Annotation ann = (Annotation)annotationsTable.getModel().
427 getValueAt(row, -1);
428 String setName = (String)annotationsTable.getModel().
430 getValueAt(row, 1);
431 AnnotationSet set = setName.equals("Default")?
432 document.getAnnotations() :
433 document.getAnnotations(setName);
434
435 EditAnnotationAction editAnnAct = new EditAnnotationAction(set, ann);
436 if(SwingUtilities.isLeftMouseButton(e)){
437 if(e.getClickCount() == 1){
438 }else if(e.getClickCount() == 2){
439 if(editable) editAnnAct.actionPerformed(null);
441 }
442 } else if(SwingUtilities.isRightMouseButton(e)) {
443 JPopupMenu popup = new XJPopupMenu();
446 popup.add(new AbstractAction(){
447 {
448 putValue(NAME, "Select all");
449 }
450 public void actionPerformed(ActionEvent evt){
451 annotationsTable.selectAll();
452 }
453 });
454
455 if(editable){
459 popup.addSeparator();
461 popup.add(new DeleteSelectedAnnotationsAction(annotationsTable));
462 popup.addSeparator();
463 popup.add(new XJMenuItem(editAnnAct, myHandle));
464 }
465 popup.show(annotationsTable, e.getX(), e.getY());
466 }
467 }
468 });
470
471
472 annotationsTable.getInputMap().put(
473 KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE, 0),
474 "Delete");
475 annotationsTable.getActionMap().put(
476 "Delete",
477 new DeleteSelectedAnnotationsAction(annotationsTable));
478
479 stylesTree.getInputMap().put(
480 KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE, 0),
481 "Delete");
482 stylesTree.getActionMap().put(
483 "Delete",
484 new DeleteSelectedAnnotationsAction(stylesTree));
485
486 corefTree.getInputMap().put(
487 KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE, 0),
488 "Delete");
489 corefTree.getActionMap().put(
490 "Delete",
491 new DeleteSelectedAnnotationsAction(corefTree));
492
493
494 annotationsTable.getSelectionModel().addListSelectionListener(
496 new ListSelectionListener(){
497 public void valueChanged(ListSelectionEvent e){
498 int[] rows = annotationsTable.getSelectedRows();
499 synchronized(selectionHighlighter){
500 selectionHighlighter.removeAllHighlights();
501 }
502 for(int i = 0; i < rows.length; i++){
503 int start = ((Long)annotationsTable.getModel().
504 getValueAt(rows[i], 2)
505 ).intValue();
506 int end = ((Long)annotationsTable.getModel().
507 getValueAt(rows[i], 3)
508 ).intValue();
509
510 start += longLinesCorrection(start);
512 end += longLinesCorrection(end);
513
514 try{
516 Rectangle startRect = textPane.modelToView(start);
517 Rectangle endRect = textPane.modelToView(end);
518 SwingUtilities.computeUnion(endRect.x, endRect.y,
519 endRect.width, endRect.height,
520 startRect);
521 textPane.scrollRectToVisible(startRect);
522 annotationsTable.requestFocus();
523 }catch(BadLocationException ble){
524 throw new GateRuntimeException(ble.toString());
525 }
526 try{
528 synchronized (selectionHighlighter){
529 selectionHighlighter.addHighlight(start, end,
530 DefaultHighlighter.DefaultPainter);
531 }
532 }catch(BadLocationException ble){
533 throw new GateRuntimeException(ble.toString());
534 }
535 } selectionBlinker.testAndStart();
538 }
539 });
540
541
542 textPane.addMouseListener(new MouseAdapter() {
543 public void mouseClicked(MouseEvent e) {
544 if(SwingUtilities.isRightMouseButton(e)){
545 int position = textPane.viewToModel(e.getPoint());
546 if(textPane.getSelectionStart() == textPane.getSelectionEnd()){
547 JPopupMenu popup = new XJPopupMenu("Select:");
549 Iterator annIter = document.getAnnotations().
551 get(new Long(position),
552 new Long(position)
553 ).iterator();
554 if(annIter.hasNext()){
555 JMenu menu = new XJMenu("Default");
556 popup.add(menu);
557 while(annIter.hasNext()){
558 Annotation ann = (Annotation)annIter.next();
559 menu.add(new HighlightAnnotationMenu(ann,
560 document.getAnnotations()));
561 }
562 }
563 Map namedASs = document.getNamedAnnotationSets();
564 if(namedASs != null){
565 Iterator namedASiter = namedASs.values().iterator();
566 while(namedASiter.hasNext()){
567 AnnotationSet set = (AnnotationSet)namedASiter.next();
569 annIter = set.get(new Long(position), new Long(position)).
570 iterator();
571 if(annIter.hasNext()){
572 JMenu menu = new XJMenu(set.getName());
573 popup.add(menu);
574 while(annIter.hasNext()){
575 Annotation ann = (Annotation)annIter.next();
576 menu.add(new HighlightAnnotationMenu(ann,set));
577 }
578 }
579 }
580 }
581 popup.show(textPane, e.getPoint().x, e.getPoint().y);
582 } else {
583 if(!editable) return;
585 Long startOffset = new Long(textPane.getSelectionStart());
586 Long endOffset = new Long(textPane.getSelectionEnd());
587 JPopupMenu popup = new XJPopupMenu();
588 JMenu menu = new XJMenu("Add annotation to \"Default\"");
590 menu.add(new XJMenuItem(
591 new NewAnnotationAction(document.getAnnotations(),
592 startOffset, endOffset),
593 myHandle));
594 java.util.List customisedAnnTypes = Gate.getCreoleRegister().
595 getVREnabledAnnotationTypes();
596 if(!customisedAnnTypes.isEmpty()){
597 menu.addSeparator();
598 Iterator typesIter = customisedAnnTypes.iterator();
599 while(typesIter.hasNext()){
600 menu.add(new XJMenuItem(
601 new NewAnnotationAction(document.getAnnotations(),
602 (String)typesIter.next(),
603 startOffset, endOffset),
604 myHandle));
605 }
606 } popup.add(menu);
608
609 if(document.getNamedAnnotationSets() != null){
611 Iterator annSetsIter = document.getNamedAnnotationSets().
612 keySet().iterator();
613 if(annSetsIter.hasNext()) popup.addSeparator();
614 while(annSetsIter.hasNext()){
615 AnnotationSet set = document.getAnnotations(
616 (String)annSetsIter.next());
617
618
619 menu = new XJMenu("Add annotation to \"" + set.getName() + "\"");
620 menu.add(new XJMenuItem(
621 new NewAnnotationAction(set, startOffset, endOffset),
622 myHandle));
623 if(!customisedAnnTypes.isEmpty()){
624 menu.addSeparator();
625 Iterator typesIter = customisedAnnTypes.iterator();
626 while(typesIter.hasNext()){
627 menu.add(new XJMenuItem(
628 new NewAnnotationAction(set,
629 (String)typesIter.next(),
630 startOffset, endOffset),
631 myHandle));
632 }
633 } popup.add(menu);
635 } }
637
638 menu = new XJMenu("Add annotation to a new set");
640 menu.add(new XJMenuItem(
641 new NewAnnotationAction(null, startOffset, endOffset),
642 myHandle));
643 if(!customisedAnnTypes.isEmpty()){
644 menu.addSeparator();
645 Iterator typesIter = customisedAnnTypes.iterator();
646 while(typesIter.hasNext()){
647 menu.add(new XJMenuItem(
648 new NewAnnotationAction(null,
649 (String)typesIter.next(),
650 startOffset, endOffset),
651 myHandle));
652 }
653 } popup.add(menu);
655 popup.show(textPane, e.getPoint().x, e.getPoint().y);
657 } } }
661 public void mousePressed(MouseEvent e) {
662 }
663
664 public void mouseReleased(MouseEvent e) {
665 }
666
667 public void mouseEntered(MouseEvent e) {
668 }
669
670 public void mouseExited(MouseEvent e) {
671 }
672 });
673
674 textPane.addPropertyChangeListener(new PropertyChangeListener() {
676 public void propertyChange(PropertyChangeEvent e) {
677 if(e.getPropertyName().equals("highlighter")){
678 highlighter = textPane.getHighlighter();
679 selectionHighlighter.install(textPane);
680 }
681 }
682 });
683
684 corefTree.addMouseListener(new MouseAdapter() {
685 public void mouseClicked(MouseEvent e) {
686 if(SwingUtilities.isLeftMouseButton(e)){
687 int x = e.getX();
689 int y = e.getY();
690 TreePath path = corefTree.getPathForLocation(x, y);
691 if(path != null){
692 DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.
693 getLastPathComponent();
694 Rectangle cellRect = corefTree.getPathBounds(path);
696 x -= cellRect.x;
697 y -= cellRect.y;
698 Component cellComp = corefTree.getCellRenderer().
699 getTreeCellRendererComponent(corefTree,
700 node, true,
701 false, false,
702 0, true);
703 cellComp.setBounds(cellRect);
704 Component clickedComp = cellComp.getComponentAt(x, y);
705 if(clickedComp instanceof LazyJPanel)
706 clickedComp = clickedComp.getComponentAt(x, y);
707 if(node.getUserObject() instanceof CorefData &&
708 clickedComp instanceof JCheckBox){
709 CorefData cData = (CorefData)node.getUserObject();
710 cData.setVisible(!cData.getVisible());
711 corefTreeModel.nodeChanged(node);
712 }
713 }
714 }
715 }
716
717 public void mousePressed(MouseEvent e) {
718 }
719
720 public void mouseReleased(MouseEvent e) {
721 }
722
723 public void mouseEntered(MouseEvent e) {
724 }
725
726 public void mouseExited(MouseEvent e) {
727 }
728 });
729
730
731
732 corefTree.addComponentListener(new ComponentAdapter() {
733 public void componentHidden(ComponentEvent e) {
734
735 }
736
737 public void componentMoved(ComponentEvent e) {
738 }
739
740 public void componentResized(ComponentEvent e) {
741 SwingUtilities.invokeLater(new Runnable(){
742 public void run(){
743 Enumeration nodes = corefTreeRoot.depthFirstEnumeration();
744 while(nodes.hasMoreElements()){
745 corefTreeModel.nodeChanged((TreeNode)nodes.nextElement());
746 }
747 }
748 });
749 }
750
751 public void componentShown(ComponentEvent e) {
752 }
753 });
754 }
756
759 protected void initLocalData(){
760 lock = new Object();
762
763 data = Collections.synchronizedList(new ArrayList());
764 ranges = new ArrayList();
766
767 typeDataMap = new HashMap();
768
769 eventHandler = new EventsHandler();
770
771 }
773
774 protected void initGuiComponents(){
775 this.setLayout(new BorderLayout());
778
779 toolbar = new JToolBar(JToolBar.HORIZONTAL);
781 toolbar.setAlignmentX(Component.LEFT_ALIGNMENT);
782 toolbar.setAlignmentY(Component.TOP_ALIGNMENT);
783 toolbar.setFloatable(false);
784 this.add(toolbar, BorderLayout.NORTH);
785
786 textVisibleBtn = new JToggleButton("Text", textVisible);
787 toolbar.add(textVisibleBtn);
788
789 annotationsTableVisibleBtn = new JToggleButton("Annotations",
790 annotationsTableVisible);
791 toolbar.add(annotationsTableVisibleBtn);
792
793 typesTreeVisibleBtn = new JToggleButton("Annotation Sets", typesTreeVisible);
794 toolbar.add(typesTreeVisibleBtn);
795
796
797 coreferenceVisibleBtn = new JToggleButton("Coreference", coreferenceVisible);
798 if(isCorefOptionAvailable()) toolbar.add(coreferenceVisibleBtn);
799
800
801 toolbar.add(Box.createHorizontalStrut(20));
803 toolbar.add(new PrintAction());
804 toolbar.add(new SearchAction());
805
806
807
808 toolbar.add(Box.createHorizontalGlue());
809
810 textPane = new XJTextPane();
812 textPane.setEnabled(true);
814 textPane.setEditorKit(new CustomStyledEditorKit());
815 Style defaultStyle = textPane.getStyle("default");
816 StyleConstants.setBackground(defaultStyle, Color.white);
817 StyleConstants.setFontFamily(defaultStyle, "Arial Unicode MS");
818 textScroll = new JScrollPane(textPane);
819 textScroll.setAlignmentY(Component.TOP_ALIGNMENT);
820 textScroll.setAlignmentX(Component.LEFT_ALIGNMENT);
821
822
823 annotationsTableModel = new AnnotationsTableModel();
825 annotationsTable = new XJTable(annotationsTableModel);
826
828 tableScroll = new JScrollPane(annotationsTable);
829 tableScroll.setOpaque(true);
830 tableScroll.setAlignmentY(Component.TOP_ALIGNMENT);
831 tableScroll.setAlignmentX(Component.LEFT_ALIGNMENT);
832
833
834 stylesTreeRoot = new DefaultMutableTreeNode(null, true);
836 stylesTreeModel = new DefaultTreeModel(stylesTreeRoot, true);
837 stylesTree = new JTree(stylesTreeModel){
838 public void updateUI(){
839 super.updateUI();
840 setRowHeight(0);
841 }
842 };
843
844 stylesTree.setRootVisible(false);
845 stylesTree.setCellRenderer(new NodeRenderer());
846 stylesTree.setRowHeight(0);
849 stylesTree.setShowsRootHandles(true);
850 stylesTree.setToggleClickCount(0);
851 stylesTreeScroll = new JScrollPane(stylesTree);
852 stylesTreeScroll.setAlignmentY(Component.TOP_ALIGNMENT);
853 stylesTreeScroll.setAlignmentX(Component.LEFT_ALIGNMENT);
854
855
856 corefTreeRoot = new DefaultMutableTreeNode("Co-reference data", true);
858 corefTree = new JTree(corefTreeModel = new DefaultTreeModel(corefTreeRoot,
859 true));
860 corefTree.setCellRenderer(new CorefNodeRenderer());
861 corefTree.setRowHeight(0);
862 corefTree.setRootVisible(true);
863 corefTree.setShowsRootHandles(false);
864 corefScroll = new JScrollPane(corefTree);
865 corefScroll.setAlignmentX(Component.LEFT_ALIGNMENT);
866 corefScroll.setAlignmentY(Component.TOP_ALIGNMENT);
867 updateCorefTree();
868
869 leftSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, false);
871 leftSplit.setOneTouchExpandable(true);
872 leftSplit.setOpaque(true);
873 leftSplit.setAlignmentY(Component.TOP_ALIGNMENT);
874 leftSplit.setAlignmentX(Component.LEFT_ALIGNMENT);
875 leftSplit.setResizeWeight((double)0.75);
876
877 rightSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, false);
878 rightSplit.setOneTouchExpandable(true);
879 rightSplit.setOpaque(true);
880 rightSplit.setAlignmentY(Component.TOP_ALIGNMENT);
881 rightSplit.setAlignmentX(Component.LEFT_ALIGNMENT);
882 rightSplit.setResizeWeight((double)0.75);
883
884
885 mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, false);
886 mainSplit.setOneTouchExpandable(true);
887 mainSplit.setOpaque(true);
888 mainSplit.setAlignmentY(Component.TOP_ALIGNMENT);
889 mainSplit.setAlignmentX(Component.LEFT_ALIGNMENT);
890 mainSplit.setResizeWeight((double)0.75);
891
892 layoutComponents();
894
895
897 progressBox = new Box(BoxLayout.X_AXIS);
898 progressBox.add(Box.createHorizontalStrut(5));
899 progressBar = new JProgressBar(JProgressBar.HORIZONTAL, 0, 100);
900 progressBox.add(progressBar);
901 progressBox.add(Box.createHorizontalStrut(5));
902
903 highlighter = textPane.getHighlighter();
904 if(highlighter instanceof javax.swing.text.DefaultHighlighter){
905 ((javax.swing.text.DefaultHighlighter)highlighter).
906 setDrawsLayeredHighlights(true);
907 }
908
909 selectionHighlighter = new DefaultHighlighter();
910 selectionHighlighter.install(textPane);
911 selectionBlinker = new SelectionBlinker();
912
913 }
915
916
917 private boolean isTextSelected(){
918 return !(textPane.getSelectionStart()==textPane.getSelectionEnd());
919 }
924 protected Set getAnnotationSchemas(){
925 Set result = new HashSet();
926 ResourceData rData = (ResourceData)Gate.getCreoleRegister().
927 get("gate.creole.AnnotationSchema");
928 if(rData != null){
929 result.addAll(rData.getInstantiations());
930 }
931 return result;
932 }
934 public synchronized void removePropertyChangeListener(
935 PropertyChangeListener l) {
936 super.removePropertyChangeListener(l);
937 propertyChangeListeners.removePropertyChangeListener(l);
938 }
939
940 public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
941 super.addPropertyChangeListener(l);
942 propertyChangeListeners.addPropertyChangeListener(l);
943 }
944
945 public synchronized void addPropertyChangeListener(String propertyName,
946 PropertyChangeListener l) {
947 super.addPropertyChangeListener(propertyName, l);
948 propertyChangeListeners.addPropertyChangeListener(propertyName, l);
949 }
950
951
952
953 public gate.Document getDocument() {
954 return document;
955 }
957
960 public void setTarget(Object target){
961 if(target == null){
962 document = null;
963 return;
964 }
965 if(!(target instanceof gate.Document)){
966 throw new IllegalArgumentException(
967 "The document editor can only display GATE documents!\n" +
968 "The provided resource is not a document but a: " +
969 target.getClass().toString() + "!");
970 }
971 gate.Document oldDocument = document;
972 document = (gate.Document)target;
973 if(oldDocument != document) this_documentChanged();
976
977 propertyChangeListeners.firePropertyChange("document", oldDocument,
978 target);
979 }
981 public void setHandle(Handle handle){
982 myHandle = handle;
983 }
984
985 public void cleanup(){
986 document = null;
987 stylesTreeRoot.removeAllChildren();
988 data.clear();
989 ranges.clear();
990 myHandle = null;
991 }
992
993
997 public java.util.Set getDisplayedAnnotations() {
998 if (annotationsTableModel == null||annotationsTableModel.getRowCount() == 0)
1000 return null;
1001
1002 java.util.Set shownAnnots = new HashSet();
1004 for(int i = 0; i < annotationsTableModel.getRowCount(); i++){
1005 Annotation ann = (Annotation)annotationsTableModel.getValueAt(i, -1);
1007 shownAnnots.add(ann);
1008 }
1010 return shownAnnots;
1011 }
1012
1013
1016 private Vector getBreakPositions(String content) {
1017 Vector breakPositions = new Vector();
1018
1019 int lastNewLinePos = -1;
1020 int spacePos = -1;
1021 int unbreakedLineSize = 0;
1022 char ch;
1023 int contentSize = content.length();
1024
1025 for(int i=0; i<contentSize; ++i) {
1026 ch = content.charAt(i);
1027
1028 switch(ch) {
1029 case '\n' :
1030 unbreakedLineSize = 0;
1031 spacePos = -1;
1032 break;
1033 case '\r' :
1034 unbreakedLineSize = 0;
1035 spacePos = -1;
1036 break;
1037 case '\t' :
1038 spacePos = i;
1039 ++unbreakedLineSize;
1040 break;
1041 case ' ' :
1042 spacePos = i;
1043 ++unbreakedLineSize;
1044 break;
1045
1046 default:
1047 if(unbreakedLineSize >= MAX_LINE_SIZE) {
1048 if(spacePos == -1) {
1050 spacePos = i;
1052 }
1054 breakPositions.add(new Integer(spacePos+1));
1055 unbreakedLineSize = i - spacePos;
1056 spacePos = -1;
1057 }
1058 else {
1059 ++unbreakedLineSize;
1060 } } }
1064 return breakPositions;
1065 }
1067
1068 private final int MAX_LINE_SIZE = 2048;
1069
1070
1076 private Vector correctLongLines(StringBuffer buff) {
1077 Vector breaks = getBreakPositions(buff.toString());
1079
1081 Integer currentBreak;
1082 int intValue;
1083 for(int i = breaks.size()-1; i>=0; --i) {
1085 currentBreak = (Integer) breaks.get(i);
1086 intValue = currentBreak.intValue();
1087 buff.insert(intValue, '\n');
1088 }
1090 if(breaks.size() > 0) {
1091 return breaks;
1092 }
1093 else {
1094 return null;
1095 }
1096 }
1098
1099 private int longLinesCorrection(int position) {
1100 int result = 0;
1101
1102 if(longLinesCorrectionPositions != null) {
1103 boolean underPosition = true;
1104 Integer current;
1105 Iterator it = longLinesCorrectionPositions.iterator();
1106
1107 while(underPosition && it.hasNext()) {
1108 current = (Integer) it.next();
1109 if(position > (current.intValue()+result)) {
1110 ++result;
1112 }
1113 else {
1114 underPosition = false;
1116 } } }
1120 return result;
1121 }
1123
1124 private Vector longLinesCorrectionPositions;
1125
1126
1131 protected void this_documentChanged(){
1132 initLocalData();
1133
1134 Enumeration enumeration = stylesTreeRoot.children();
1135 while(enumeration.hasMoreElements()){
1136 stylesTreeModel.removeNodeFromParent((DefaultMutableTreeNode)
1137 enumeration.nextElement());
1138 }
1139 if(document == null) return;
1140
1141 String documentContent = document.getContent().toString();
1143 StringBuffer buffContent = new StringBuffer(documentContent);
1144 longLinesCorrectionPositions = correctLongLines(buffContent);
1146 if(longLinesCorrectionPositions != null) {
1147 documentContent = buffContent.toString();
1148 }
1150 textPane.setText(documentContent);
1151 textPane.getDocument().addDocumentListener(new SwingDocumentListener());
1153
1154 eventHandler.annotationSetAdded(new gate.event.DocumentEvent(
1156 document,
1157 gate.event.DocumentEvent.ANNOTATION_SET_ADDED, null));
1158
1159 document.addDocumentListener(eventHandler);
1161
1162 annotationsTableModel.fireTableDataChanged();
1163 document.getFeatures().addFeatureMapListener(new FeatureMapListener(){
1164 public void featureMapUpdated(){
1165 updateCorefTree();
1166 }
1167 });
1168 updateCorefTree();
1169
1170
1171 Map namedASs = document.getNamedAnnotationSets();
1173 if(namedASs != null){
1174 Iterator setsIter = namedASs.values().iterator();
1175 while(setsIter.hasNext()){
1176 AnnotationSet currentAS = (AnnotationSet)setsIter.next();
1177 if(currentAS != null){
1178 eventHandler.annotationSetAdded(new gate.event.DocumentEvent(
1179 document,
1180 gate.event.DocumentEvent.ANNOTATION_SET_ADDED,
1181 currentAS.getName()));
1182 }
1183 }
1184 }
1185 }
1187
1200 protected TypeData getTypeData(String setName, String type){
1201 Map setMap = (Map)typeDataMap.get(setName);
1202 if(setMap != null) return (TypeData)setMap.get(type);
1203 else return null;
1204 }
1206
1207
1210 protected void showHighlights(Set annotations, AttributeSet style) {
1211 int selStart = textPane.getSelectionStart();
1213 int selEnd = textPane.getSelectionEnd();
1214 final int position = textPane.viewToModel(
1215 textScroll.getViewport().getViewPosition());
1216 SwingUtilities.invokeLater(new Runnable() {
1218 public void run() {
1219 progressBar.setValue(0);
1220 textScroll.getViewport().setView(progressBox);
1222 textScroll.paintImmediately(textScroll.getBounds());
1223 }
1224 });
1225
1226 paintHighlights(annotations, style);
1227
1228 textPane.select(selStart, selEnd);
1230 SwingUtilities.invokeLater(new Runnable() {
1231 public void run() {
1232 textScroll.getViewport().setView(textPane);
1234 try {
1235 textScroll.getViewport().setViewPosition(
1236 textPane.modelToView(position).getLocation());
1237 textScroll.paintImmediately(textScroll.getBounds());
1238 }
1239 catch (BadLocationException ble) {
1240 }
1241 }
1242 });
1243 }
1245 protected void paintHighlights(Set annotations, AttributeSet style){
1246 int size = annotations.size();
1248 int i = 0;
1249 int lastValue = 0;
1250 int value;
1251
1252 int start, end;
1253 Iterator annIter = annotations.iterator();
1254 while(annIter.hasNext()){
1255 Annotation ann = (Annotation)annIter.next();
1256 start = ann.getStartNode().getOffset().intValue();
1257 end = ann.getEndNode().getOffset().intValue();
1258 start += longLinesCorrection(start);
1260 end += longLinesCorrection(end);
1261
1262 textPane.select(start, end);
1263 textPane.setCharacterAttributes(style, true);
1264 if(progressBar.isVisible()){
1265 value = i * 100 / size;
1266 if (value - lastValue >= 5) {
1267 progressBar.setValue(value);
1268 progressBar.paintImmediately(progressBar.getBounds());
1269 lastValue = value;
1270 }
1271 i++;
1272 }
1273 }
1274 }
1275
1276
1282 protected void repairHighlights(int start, int end) {
1283 int selStart = textPane.getSelectionStart();
1286 int selEnd = textPane.getSelectionEnd();
1287 textPane.select(start, end);
1289 textPane.setCharacterAttributes(textPane.getStyle("default"), true);
1290
1291 Iterator setsIter = typeDataMap.keySet().iterator();
1293 while(setsIter.hasNext()){
1294 Map typesMap = (Map)typeDataMap.get(setsIter.next());
1295 Iterator typesIter = typesMap.keySet().iterator();
1296 while(typesIter.hasNext()){
1297 TypeData tData = (TypeData) typesMap.get(typesIter.next());
1298 if (tData.getVisible()) {
1299 String setName = tData.getSet();
1300 AnnotationSet annSet = setName.equals("Default") ?
1301 document.getAnnotations() :
1302 document.getAnnotations(setName);
1303 annSet = annSet.get(tData.getType());
1304 if(annSet != null){
1305 AnnotationSet annotationsToRepaint = annSet.get(new Long(start),
1306 new Long(end));
1307 paintHighlights(annotationsToRepaint, tData.getActualStyle());
1319 }
1320 }
1321 }
1322 }
1323 textPane.select(selStart, selEnd);
1325 }
1327
1328
1333 protected void selectAnnotation(String set, Annotation ann) {
1334 TypeData tData = getTypeData(set, ann.getType());
1335 if(!tData.getVisible()){
1336 tData.setVisible(true);
1337 try{
1339 Thread.sleep(100);
1340 }catch(InterruptedException ie){}
1341 DefaultMutableTreeNode node = (DefaultMutableTreeNode)
1344 ((DefaultMutableTreeNode)stylesTreeRoot).
1345 getFirstChild();
1346 while(node != null &&
1347 !((TypeData)node.getUserObject()).getSet().equals(set))
1348 node = node.getNextSibling();
1349 if(node != null){
1350 node = (DefaultMutableTreeNode)node.getFirstChild();
1351 String type = ann.getType();
1352 while(node != null &&
1353 !((TypeData)node.getUserObject()).getType().equals(type))
1354 node = node.getNextSibling();
1355 if(node != null) stylesTreeModel.nodeChanged(node);
1356 }
1357 }
1358 int position = -1;
1359 position = data.indexOf(ann);
1360 if(position != -1){
1361 position = annotationsTable.getTableRow(position);
1362 if(position != -1){
1363 annotationsTable.clearSelection();
1364 annotationsTable.addRowSelectionInterval(position, position);
1365 annotationsTable.scrollRectToVisible(
1366 annotationsTable.getCellRect(position, 0, true));
1367 }
1368 }
1369 }
1371
1372
1376 protected void layoutComponents(){
1377 SwingUtilities.invokeLater(new Runnable(){
1378 public void run(){
1379 Component leftComp = null, rightComp = null;
1380 if(isTextVisible() && isAnnotationsTableVisible()){
1381 leftSplit.setTopComponent(textScroll);
1382 leftSplit.setBottomComponent(tableScroll);
1383 leftComp = leftSplit;
1384 }else{
1385 if(isTextVisible()) leftComp = textScroll;
1386 else if(isAnnotationsTableVisible()) leftComp = tableScroll;
1387 }
1388
1389 boolean corefDisplayed = isCoreferenceVisible() &&
1390 isCorefOptionAvailable();
1391 if(corefDisplayed) updateCorefTree();
1392 if(isTypesTreeVisible() && corefDisplayed){
1393 rightSplit.setTopComponent(stylesTreeScroll);
1394 rightSplit.setBottomComponent(corefScroll);
1395 rightComp = rightSplit;
1396 }else{
1397 if(isTypesTreeVisible()) rightComp = stylesTreeScroll;
1398 else if(corefDisplayed) rightComp = corefScroll;
1399 }
1400
1401 if(DocumentEditor.this.getComponentCount() > 1)
1402 DocumentEditor.this.remove(1);
1403 if(leftComp != null && rightComp != null){
1404 mainSplit.setLeftComponent(leftComp);
1406 mainSplit.setRightComponent(rightComp);
1407 DocumentEditor.this.add(mainSplit, BorderLayout.CENTER);
1408 }else{
1409 if(leftComp != null) DocumentEditor.this.add(leftComp,
1410 BorderLayout.CENTER);
1411 else if(rightComp != null)DocumentEditor.this.add(rightComp,
1412 BorderLayout.CENTER);
1413 }
1414
1415 DocumentEditor.this.validate();
1416 DocumentEditor.this.repaint();
1417 }
1418 });
1419 }
1420
1421
1422
1425 protected void updateCorefTree(){
1426 if(document == null || document.getFeatures() == null){
1427 corefTreeRoot.removeAllChildren();
1429 corefTreeModel.nodeStructureChanged(corefTreeRoot);
1430 setCorefOptionAvailable(false);
1431 return;
1432 }
1433
1434 Map matchesMap = null;
1435 try{
1436 matchesMap = (Map)document.getFeatures().get(DOCUMENT_COREF_FEATURE_NAME);
1437 }catch(Exception e){
1438 }
1439 if(matchesMap == null){
1440 Enumeration nodes = corefTreeRoot.breadthFirstEnumeration();
1442 while(nodes.hasMoreElements()){
1443 DefaultMutableTreeNode node = (DefaultMutableTreeNode)
1444 nodes.nextElement();
1445 if(node.getUserObject() instanceof CorefData){
1446 ((CorefData)node.getUserObject()).setVisible(false);
1447 }
1448 }
1449 corefTreeRoot.removeAllChildren();
1450 corefTreeModel.nodeStructureChanged(corefTreeRoot);
1451 setCorefOptionAvailable(false);
1452 return;
1453 }
1454
1455 Iterator setsIter = matchesMap.keySet().iterator();
1457 setsLoop: while(setsIter.hasNext()){
1458 String setName = (String)setsIter.next();
1459 AnnotationSet annSet = setName == null ? document.getAnnotations() :
1460 document.getAnnotations(setName);
1461 Iterator entitiesIter = ((java.util.List)matchesMap.get(setName)).
1462 iterator();
1463 while(entitiesIter.hasNext()){
1465 Iterator idsIter = ((java.util.List)entitiesIter.next()).iterator();
1466 while(idsIter.hasNext()){
1467 if(annSet.get((Integer)idsIter.next()) == null){
1468 setsIter.remove();
1470 Err.prln("Coreference data for the \"" +
1471 (setName == null ? "Default" : setName) +
1472 "\" annotation set of document \"" + document.getName() +
1473 "\" was invalid and has been removed");
1474 continue setsLoop;
1475 }
1476 }
1477 }
1478 }
1479
1480 if(matchesMap.isEmpty()){
1481 corefTreeRoot.removeAllChildren();
1483 corefTreeModel.nodeStructureChanged(corefTreeRoot);
1484 setCorefOptionAvailable(false);
1485 return;
1486 }
1487
1488 String[] newSetNames = (String[])
1489 matchesMap.keySet().toArray(new String[]{});
1490 Arrays.sort(newSetNames);
1491
1492 ArrayList oldSetNames = new ArrayList(corefTreeRoot.getChildCount());
1493 Enumeration setNodes = corefTreeRoot.children();
1494 while(setNodes.hasMoreElements()){
1495 String oldSetName = (String)
1496 ((DefaultMutableTreeNode)setNodes.nextElement()).
1497 getUserObject();
1498 oldSetNames.add(oldSetName.equals("Default") ? null : oldSetName);
1499 }
1500
1501
1502 ArrayList newSetNodes = new ArrayList();
1505 for(int i =0; i < newSetNames.length; i++){
1507 String setName = newSetNames[i];
1508 int oldNodeIndex = oldSetNames.indexOf(setName);
1509 DefaultMutableTreeNode setNode =
1510 (oldNodeIndex != -1) ?
1511 (DefaultMutableTreeNode)
1512 corefTreeRoot.getChildAt(oldNodeIndex) :
1513 new DefaultMutableTreeNode((setName == null ? "Default" : setName),
1514 true);
1515 if(oldNodeIndex != -1) oldSetNames.remove(oldNodeIndex);
1517
1518 ArrayList newEntityNodes = new ArrayList();
1520 Iterator corefDataIter = ((java.util.List)matchesMap.get(setName)).
1522 iterator();
1523 while(corefDataIter.hasNext()){
1524 java.util.List newAnnotIDs = (java.util.List)corefDataIter.next();
1525 CorefData cData = null;
1526 DefaultMutableTreeNode entityNode = null;
1527 Enumeration entityNodes = setNode.children();
1529 while(cData == null && entityNodes.hasMoreElements()){
1530 entityNode = (DefaultMutableTreeNode)entityNodes.nextElement();
1531 java.util.List oldAnnotIDs = ((CorefData)entityNode.getUserObject()).
1532 getAnnoationIDs();
1533 java.util.List intersection = new ArrayList(oldAnnotIDs);
1534 intersection.retainAll(newAnnotIDs);
1535 if(!intersection.isEmpty()){
1536 cData = (CorefData)entityNode.getUserObject();
1538 if(intersection.size() == newAnnotIDs.size()){
1539 }else{
1541 cData.setAnnotationIDs(newAnnotIDs);
1542 }
1543 }
1544 }
1545 if(cData == null){
1546 cData = new CorefData(newAnnotIDs, false, setName == null ?
1548 "Default" : setName);
1549 entityNode = new DefaultMutableTreeNode(cData, false);
1550 }
1551 newEntityNodes.add(entityNode);
1552 }
1564 setNode.removeAllChildren();
1565 for(Iterator nodesIter = newEntityNodes.iterator();
1566 nodesIter.hasNext();
1567 setNode.add((DefaultMutableTreeNode)nodesIter.next())){
1568 }
1569 newSetNodes.add(setNode);
1570 } corefTreeRoot.removeAllChildren();
1573 for(Iterator nodesIter = newSetNodes.iterator();
1574 nodesIter.hasNext();){
1575 DefaultMutableTreeNode setNode = (DefaultMutableTreeNode)nodesIter.next();
1576 corefTreeRoot.add(setNode);
1577 }
1578 SwingUtilities.invokeLater(new Runnable(){
1579 public void run(){
1580 highlighter.removeAllHighlights();
1581 corefTreeModel.nodeStructureChanged(corefTreeRoot);
1582 corefTree.expandPath(new TreePath(new Object[]{corefTreeRoot}));
1584 Enumeration children = corefTreeRoot.children();
1586 while(children.hasMoreElements()){
1587 DefaultMutableTreeNode aNode =
1588 (DefaultMutableTreeNode)children.nextElement();
1589 corefTree.expandPath(
1590 new TreePath(corefTreeModel.getPathToRoot(aNode)));
1591 if(aNode.getUserObject() instanceof CorefData){
1592 CorefData cData = (CorefData)aNode.getUserObject();
1593 cData.setVisible(cData.getVisible());
1595 }
1596 }
1597 }
1598 });
1599 setCorefOptionAvailable(true);
1600 }
1602
1603
1604 public void setEditable(boolean newEditable) {
1605 editable = newEditable;
1606 }
1607
1608
1609 public boolean isEditable() {
1610 return editable;
1611 }
1612 public void setAnnotationsTableVisible(boolean annotationsTableVisible) {
1613 boolean oldAnnotationsTableVisible = this.annotationsTableVisible;
1614 this.annotationsTableVisible = annotationsTableVisible;
1615 propertyChangeListeners.firePropertyChange(
1616 "annotationsTableVisible",
1617 new Boolean(oldAnnotationsTableVisible),
1618 new Boolean(annotationsTableVisible));
1619 }
1620 public boolean isAnnotationsTableVisible() {
1621 return annotationsTableVisible;
1622 }
1623 public void setCoreferenceVisible(boolean coreferenceVisible) {
1624 boolean oldCoreferenceVisible = this.coreferenceVisible;
1625 this.coreferenceVisible = coreferenceVisible;
1626 propertyChangeListeners.firePropertyChange(
1627 "coreferenceVisible",
1628 new Boolean(oldCoreferenceVisible),
1629 new Boolean(coreferenceVisible));
1630 }
1631
1632 public boolean isCoreferenceVisible() {
1633 return coreferenceVisible;
1634 }
1635 public void setTextVisible(boolean textVisible) {
1636 boolean oldTextVisible = this.textVisible;
1637 this.textVisible = textVisible;
1638 propertyChangeListeners.firePropertyChange("textVisible",
1639 new Boolean(oldTextVisible),
1640 new Boolean(textVisible));
1641 }
1642 public boolean isTextVisible() {
1643 return textVisible;
1644 }
1645 public void setTypesTreeVisible(boolean typesTreeVisible) {
1646 boolean oldTypesTreeVisible = this.typesTreeVisible;
1647 this.typesTreeVisible = typesTreeVisible;
1648 propertyChangeListeners.firePropertyChange("typesTreeVisible",
1649 new Boolean(oldTypesTreeVisible),
1650 new Boolean(typesTreeVisible));
1651 }
1652 public boolean isTypesTreeVisible() {
1653 return typesTreeVisible;
1654 }
1655 public void setCorefOptionAvailable(boolean corefOptionAvailable) {
1656 boolean oldCorefOptionAvailable = this.corefOptionAvailable;
1657 this.corefOptionAvailable = corefOptionAvailable;
1658 propertyChangeListeners.firePropertyChange(
1659 "corefOptionAvailable", new Boolean(oldCorefOptionAvailable),
1660 new Boolean(corefOptionAvailable));
1661 }
1662
1663 public boolean isCorefOptionAvailable() {
1664 return corefOptionAvailable;
1665 }
1666
1667
1673 protected class AnnotationsTableModel extends AbstractTableModel{
1674 public AnnotationsTableModel(){
1675 }
1676
1677 public int getRowCount(){
1678 return data.size();
1679 }
1680
1681 public int getColumnCount(){
1682 return 5;
1683 }
1684
1685 public String getColumnName(int column){
1686 switch(column){
1687 case 0: return "Type";
1688 case 1: return "Set";
1689 case 2: return "Start";
1690 case 3: return "End";
1691 case 4: return "Features";
1692 default:return "?";
1693 }
1694 }
1695
1696 public Class getColumnClass(int column){
1697 switch(column){
1698 case 0: return String.class;
1699 case 1: return String.class;
1700 case 2: return Long.class;
1701 case 3: return Long.class;
1702 case 4: return String.class;
1703 default:return Object.class;
1704 }
1705 }
1706
1707 public Object getValueAt(int row, int column){
1708 Annotation ann;
1709 ann = (Annotation)data.get(row);
1710 switch(column){
1711 case -1:{ return ann;
1713 }
1714 case 0:{ return ann.getType();
1716 }
1717 case 1:{ Iterator rangesIter = ranges.iterator();
1719 while(rangesIter.hasNext()){
1720 Range range = (Range)rangesIter.next();
1721 if(range.start <= row && row < range.end) return range.setName;
1722 }
1723 return "?";
1724 }
1725 case 2:{ return ann.getStartNode().getOffset();
1727 }
1728 case 3:{ return ann.getEndNode().getOffset();
1730 }
1731 case 4:{ if(ann.getFeatures() == null) return null;
1733 else return ann.getFeatures().toString();
1734 }
1735 default:{
1736 }
1737 }
1738 return null;
1739 }
1740 }
1742
1743 protected class CorefData{
1744 CorefData(java.util.List annotationIDs, boolean visible, String setName){
1745 this.visible = visible;
1746 this.setName = setName;
1747 this.colour = colGenerator.getNextColor();
1748 highlights = new ArrayList();
1749 this.annotationIDs = annotationIDs;
1750 this.title = getNameForCorefList(annotationIDs);
1751 }
1752
1753
1758 String getNameForCorefList(java.util.List list){
1759 if(list == null || list.isEmpty()) return null;
1760 Integer id = (Integer)list.get(0);
1761 AnnotationSet set = setName.equals("Default") ?
1762 document.getAnnotations() :
1763 document.getAnnotations(setName);
1764 Annotation ann = set.get(id);
1765
1766 String name = null;
1767 try{
1768 name = document.getContent().
1769 getContent(ann.getStartNode().getOffset(),
1770 ann.getEndNode().getOffset()).toString();
1771 }catch(InvalidOffsetException ioe){
1772 }
1773 return name;
1774 }
1775
1776 public boolean getVisible(){
1777 return visible;
1778 }
1779
1780 public void removeAnnotations(){
1781 AnnotationSet set = setName.equals("Default") ?
1782 document.getAnnotations() :
1783 document.getAnnotations(setName);
1784
1785 Iterator idIter = annotationIDs.iterator();
1786 while(idIter.hasNext()){
1787 set.remove(set.get((Integer)idIter.next()));
1788 }
1789 ((java.util.List)((Map)document.getFeatures().
1790 get(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME)).
1791 get(setName.equals("Default") ? null : setName)).remove(annotationIDs);
1792 annotationIDs.clear();
1793 updateCorefTree();
1794 }
1795
1796 public void setVisible(boolean isVisible){
1797 if(this.visible == isVisible) return;
1798 this.visible = isVisible;
1799 if(visible){
1800 AnnotationSet set = setName.equals("Default") ?
1802 document.getAnnotations() :
1803 document.getAnnotations(setName);
1804 Iterator idIter = annotationIDs.iterator();
1805 ArrayList invalidIDs = new ArrayList();
1806 while(idIter.hasNext()){
1807 Integer id = (Integer)idIter.next();
1808 Annotation ann = set.get(id);
1809 if(ann == null){
1810 invalidIDs.add(id);
1811 }else try{
1812 highlights.add(highlighter.addHighlight(
1813 ann.getStartNode().getOffset().intValue(),
1814 ann.getEndNode().getOffset().intValue(),
1815 new DefaultHighlighter.DefaultHighlightPainter(colour)));
1816 }catch(BadLocationException ble){
1817 ble.printStackTrace();
1818 }
1819 }
1820 if(!invalidIDs.isEmpty()){
1821 annotationIDs.removeAll(invalidIDs);
1822 }
1823 }else{
1824 if(!highlights.isEmpty()){
1826 Iterator hlIter = highlights.iterator();
1827 while(hlIter.hasNext()){
1828 Object tag = hlIter.next();
1829 highlighter.removeHighlight(tag);
1830 hlIter.remove();
1831 }
1832 }
1833 }
1834 }
1835
1836 public String getTitle(){
1837 return title;
1838 }
1839
1840 public Color getColour(){
1841 return colour;
1842 }
1843
1844 public void setColour(Color newColour){
1845 this.colour = newColour;
1846 if(visible){
1847 setVisible(false);
1849 setVisible(true);
1850 }
1851 }
1852
1853 public java.util.List getAnnoationIDs(){
1854 return annotationIDs;
1855 }
1856
1857 public String getSetName(){
1858 return setName;
1859 }
1860 public String toString(){
1861 return title;
1862 }
1863
1864 public void setAnnotationIDs(java.util.List newAnnIDs){
1865 this.annotationIDs =newAnnIDs;
1866 this.title = getNameForCorefList(annotationIDs);
1867 if(visible){
1868 setVisible(false);
1870 setVisible(true);
1871 }
1872 }
1873
1874 private boolean visible;
1875 private String title;
1876 private String setName;
1877 private Color colour;
1878 private java.util.List highlights;
1879 private java.util.List annotationIDs;
1880 }
1881
1882
1941
1942
1945 class LazyJPanel extends JPanel{
1946
1949 public void revalidate() {}
1950
1951
1954 public void repaint(long tm, int x, int y, int width, int height) {}
1955
1956
1959 public void repaint(Rectangle r) {}
1960
1961
1964 protected void firePropertyChange(String propertyName, Object oldValue,
1965 Object newValue) {}
1966
1967
1970 public void firePropertyChange(String propertyName, byte oldValue,
1971 byte newValue) {}
1972
1973
1976 public void firePropertyChange(String propertyName, char oldValue,
1977 char newValue) {}
1978
1979
1982 public void firePropertyChange(String propertyName, short oldValue,
1983 short newValue) {}
1984
1985
1988 public void firePropertyChange(String propertyName, int oldValue,
1989 int newValue) {}
1990
1991
1994 public void firePropertyChange(String propertyName, long oldValue,
1995 long newValue) {}
1996
1997
2000 public void firePropertyChange(String propertyName, float oldValue,
2001 float newValue) {}
2002
2003
2006 public void firePropertyChange(String propertyName, double oldValue,
2007 double newValue) {}
2008
2009
2012 public void firePropertyChange(String propertyName, boolean oldValue,
2013 boolean newValue) {}
2014 }
2015
2016
2019 class CorefNodeRenderer implements TreeCellRenderer{
2020
2021 CorefNodeRenderer(){
2022 label = new JLabel();
2023 label.setOpaque(true);
2024
2025 checkBox = new JCheckBox();
2026 checkBox.setBorderPaintedFlat(true);
2027
2028 panel = new LazyJPanel();
2029 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
2030 panel.setOpaque(false);
2031
2032 hBox = new LazyJPanel();
2033 hBox.setLayout(new BoxLayout(hBox, BoxLayout.X_AXIS));
2034 hBox.setOpaque(false);
2035
2036 panel.add(Box.createVerticalStrut(2));
2037 panel.add(hBox);
2038 panel.add(Box.createVerticalStrut(2));
2039
2040 leftSpacer = Box.createHorizontalStrut(3);
2041 rightSpacer = Box.createHorizontalStrut(3);
2042
2043 selectedBorder = BorderFactory.createLineBorder(Color.blue, 1);
2044 normalBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1);
2045 }
2046
2047 public Component getTreeCellRendererComponent(JTree tree,
2048 Object value,
2049 boolean selected,
2050 boolean expanded,
2051 boolean leaf,
2052 int row,
2053 boolean hasFocus){
2054
2055 hBox.removeAll();
2056 hBox.add(leftSpacer);
2057
2058 if(value instanceof DefaultMutableTreeNode){
2059 value = ((DefaultMutableTreeNode)value).getUserObject();
2060 }
2061 if(value instanceof CorefData){
2062 CorefData cData = (CorefData)value;
2063 checkBox.setSelected(cData.getVisible());
2064 checkBox.setBackground(tree.getBackground());
2065
2066 label.setBackground(cData.getColour());
2067 label.setForeground(tree.getForeground());
2068 label.setText(cData.getTitle());
2069 label.setFont(tree.getFont());
2070 hBox.add(checkBox);
2071 hBox.add(label);
2072 hBox.add(rightSpacer);
2073 }else{
2074 label.setText(value == null ? "" : value.toString());
2075 label.setForeground(tree.getForeground());
2076 label.setBackground(tree.getBackground());
2077 label.setFont(tree.getFont());
2078 hBox.add(label);
2079 }
2080 if(selected) panel.setBorder(selectedBorder);
2081 else panel.setBorder(normalBorder);
2082 return panel;
2083 }
2084
2085 JLabel label;
2086 JCheckBox checkBox;
2087 JPanel panel;
2088 JPanel hBox;
2089 Border selectedBorder;
2090 Border normalBorder;
2091 Component leftSpacer, rightSpacer;
2092 }
2093
2094
2097 class CorefNodeRenderer1 implements TreeCellRenderer{
2098
2099 CorefNodeRenderer1(){
2100 label = new JLabel();
2101 label.setOpaque(true);
2102
2103 toggleButton = new JToggleButton();
2104 toggleButton.setMargin(new Insets(0,3,0,3));
2105
2106 panel = new LazyJPanel();
2107 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
2108 panel.setOpaque(false);
2109 topSpacer = Box.createVerticalStrut(2);
2110 bottomSpacer = Box.createVerticalStrut(2);
2111
2112 selectedBorder = BorderFactory.createLineBorder(Color.blue, 1);
2113 normalBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1);
2114
2115 }
2116
2117 public Component getTreeCellRendererComponent(JTree tree,
2118 Object value,
2119 boolean selected,
2120 boolean expanded,
2121 boolean leaf,
2122 int row,
2123 boolean hasFocus){
2124
2125 panel.removeAll();
2126 panel.add(topSpacer);
2127
2128 if(value instanceof DefaultMutableTreeNode){
2129 value = ((DefaultMutableTreeNode)value).getUserObject();
2130 }
2131 if(value instanceof CorefData){
2132 CorefData cData = (CorefData)value;
2133 toggleButton.setSelected(cData.getVisible());
2134 toggleButton.setBackground(cData.getColour());
2135 toggleButton.setForeground(tree.getForeground());
2136 toggleButton.setText(cData.getTitle());
2137 toggleButton.setFont(tree.getFont());
2138 panel.add(toggleButton);
2139 }else{
2140 label.setText(value.toString());
2141 label.setForeground(tree.getForeground());
2142 label.setBackground(tree.getBackground());
2143 label.setFont(tree.getFont());
2144 panel.add(label);
2145 }
2146 panel.add(bottomSpacer);
2147 if(selected) panel.setBorder(selectedBorder);
2148 else panel.setBorder(normalBorder);
2149 return panel;
2150 }
2151
2152 JLabel label;
2153 JToggleButton toggleButton;
2154 JPanel panel;
2155 Border selectedBorder;
2156 Border normalBorder;
2157 Component topSpacer, bottomSpacer;
2158 }
2159
2160
2161
2173 class NodeRenderer extends LazyJPanel implements TreeCellRenderer{
2174
2175 public NodeRenderer(){
2176 visibleChk = new JCheckBox("",false);
2177 visibleChk.setOpaque(false);
2178 visibleChk.setBorderPaintedFlat(true);
2179
2180 label = new JLabel();
2181 label.setOpaque(true);
2182 fontAttrs = new HashMap();
2183 selectedBorder = BorderFactory.createLineBorder(Color.blue, 1);
2184 normalBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1);
2185 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
2186 setOpaque(false);
2187 spacer = Box.createHorizontalStrut(3);
2188 }
2189
2190 public Component getTreeCellRendererComponent(JTree tree,
2191 Object value,
2192 boolean selected,
2193 boolean expanded,
2194 boolean leaf,
2195 int row,
2196 boolean hasFocus){
2197 removeAll();
2198 add(spacer);
2199
2200 int width = spacer.getWidth();
2201
2202
2203 TypeData nData = (TypeData)
2204 ((DefaultMutableTreeNode)value).getUserObject();
2205
2206 if(nData != null){
2207 label.setText(nData.getTitle());
2208 setLabelAttributes(nData.getAttributes());
2209
2210 if(nData.getType() != null) {
2211 visibleChk.setSelected(nData.getVisible());
2212 add(visibleChk);
2213 width += visibleChk.getMinimumSize().width;
2214 }
2215 }else{
2216 label.setText(((value == null || value.toString() == null) ?
2217 "" : value.toString()));
2218 }
2219 add(label);
2220
2221 if(selected) setBorder(selectedBorder);
2222 else setBorder(normalBorder);
2223 return this;
2224 }
2226 protected void setLabelAttributes(AttributeSet style){
2227 label.setForeground(StyleConstants.getForeground(style));
2228 label.setBackground(StyleConstants.getBackground(style));
2229 fontAttrs.clear();
2230 fontAttrs.put(TextAttribute.FAMILY, StyleConstants.getFontFamily(style));
2231 fontAttrs.put(TextAttribute.SIZE, new Float(StyleConstants.getFontSize(style)));
2232 if(StyleConstants.isBold(style))
2233 fontAttrs.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
2234 else fontAttrs.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
2235 if(StyleConstants.isItalic(style))
2236 fontAttrs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
2237 else fontAttrs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
2238 if(StyleConstants.isUnderline(style))
2239 fontAttrs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
2240 else fontAttrs.remove(TextAttribute.UNDERLINE);
2241 if(StyleConstants.isStrikeThrough(style))
2242 fontAttrs.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
2243 else fontAttrs.remove(TextAttribute.STRIKETHROUGH);
2244 if(StyleConstants.isSuperscript(style))
2245 fontAttrs.put(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER);
2246 else if(StyleConstants.isSubscript(style))
2247 fontAttrs.put(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB);
2248 else fontAttrs.remove(TextAttribute.SUPERSCRIPT);
2249
2250 label.setFont(new Font(fontAttrs));
2251 }
2252
2253 Border selectedBorder;
2254 Border normalBorder;
2255 JCheckBox visibleChk;
2256 JLabel label;
2257 Map fontAttrs;
2258 Component spacer;
2259 }
2272 class NodeRenderer1 extends LazyJPanel implements TreeCellRenderer{
2273
2274 public NodeRenderer1(){
2275 visibleChk = new JCheckBox("",false);
2276 visibleChk.setOpaque(false);
2277 visibleChk.setBorderPaintedFlat(true);
2278 textComponent = new JTextPane();
2279 selectedBorder = BorderFactory.createLineBorder(Color.blue, 1);
2280 normalBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1);
2281 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
2282 setOpaque(false);
2283 spacer = Box.createHorizontalStrut(3);
2284 }
2285
2286 public Component getTreeCellRendererComponent(JTree tree,
2287 Object value,
2288 boolean selected,
2289 boolean expanded,
2290 boolean leaf,
2291 int row,
2292 boolean hasFocus){
2293 removeAll();
2294 add(spacer);
2295
2296 int width = spacer.getWidth();
2297
2298 textComponent.setSize(1000, 1000);
2300
2301 TypeData nData = (TypeData)
2302 ((DefaultMutableTreeNode)value).getUserObject();
2303
2305 if(nData != null){
2306 textComponent.setText(nData.getTitle());
2307 textComponent.selectAll();
2308 textComponent.setCharacterAttributes(nData.getAttributes(), false);
2309 textComponent.select(0, 0);
2310
2318 if(nData.getType() != null) {
2319 visibleChk.setSelected(nData.getVisible());
2320 add(visibleChk);
2321 width += visibleChk.getMinimumSize().width;
2322 }
2323 }else{
2324 textComponent.setText(((value == null || value.toString() == null) ?
2325 "" : value.toString()));
2326 }
2334 setTextComponentSize(textComponent);
2335 add(textComponent);
2336 width += textComponent.getPreferredSize().width;
2337 if(selected) setBorder(selectedBorder);
2338 else setBorder(normalBorder);
2339 width += getInsets().left + getInsets().right;
2340 setPreferredSize(null);
2341 setPreferredSize(new Dimension(width, super.getPreferredSize().height));
2342 return this;
2343 }
2345 protected void setTextComponentSize(JTextComponent comp){
2346 try{
2347 if(comp.getDocument() == null || comp.getDocument().getLength() <= 0){
2348 return;
2349 }
2350 int width = 0;
2351 Rectangle rect = comp.modelToView(0);
2352 int height = rect.height;
2353 int length = comp.getDocument().getLength();
2354 if(length > 0){
2355 Rectangle rect2 = comp.modelToView(length );
2356 if(rect2 != null){
2357 if(rect.x < rect2.x){
2358 width = rect2.x + rect2.width - rect.x;
2360 }else{
2361 width = rect.x +rect.width - rect2.x;
2363 }
2364 height = Math.max(height, rect2.height);
2365 }
2366 }
2367 Insets insets = comp.getInsets();
2368 Dimension dim = new Dimension(width + insets.left + insets.right + 5,
2369 height + insets.top + insets.bottom);
2370 comp.setPreferredSize(dim);
2371 }catch(BadLocationException ble){
2372 }
2374 }
2375 Border selectedBorder;
2376 Border normalBorder;
2377 JCheckBox visibleChk;
2378 JTextPane textComponent;
2379 Component spacer;
2380 }
2382
2394
2509
2524 public class TypeData {
2525
2526 public TypeData(String set, String type, boolean visible){
2527 this.set = set;
2528 this.type = type;
2529 this.visible = visible;
2530 Map setMap = (Map)typeDataMap.get(set);
2531 if(setMap == null){
2532 setMap = new HashMap();
2533 typeDataMap.put(set, setMap);
2534 }
2535 if(type == null) {
2536 style = textPane.addStyle(set, textPane.getStyle("default"));
2538 } else {
2539 style = textPane.addStyle(set + "." + type, textPane.getStyle(set));
2540 StyleConstants.setBackground(style,
2541 colGenerator.getNextColor().brighter());
2542 middleStyle = visible ?
2544 textPane.addStyle("_" + set + "." + type, style) :
2545 textPane.addStyle("_" + set + "." + type,
2546 textPane.getStyle("default"));
2547 actualStyle = textPane.addStyle("_" + set + "." + type + "_",
2549 textPane.getStyle("_" + set + "." + type));
2550 setMap.put(type, this);
2551 }
2552 }
2553
2554 public String getSet() { return set;}
2555
2556 public void setSet(String set) {this.set = set;}
2557
2558 public String getType() {return type;}
2559
2560 public String getTitle() {return (type == null) ? set + " annotations" :
2561 type;}
2562 public boolean getVisible() {return visible;}
2563
2564 public void setVisible(boolean isVisible) {
2565 if(this.visible == isVisible) return;
2566 this.visible = isVisible;
2567 Runnable runnable = new Runnable() {
2571 public void run() {
2572 if(visible) {
2573 synchronized(data) {
2576 range = new Range(set, type, data.size(),
2577 data.size() + annotations.size());
2578 ranges.add(range);
2579 data.addAll(annotations);
2580 SwingUtilities.invokeLater(new Runnable() {
2581 public void run() {
2582 annotationsTableModel.fireTableDataChanged();
2583 }
2584 });
2585 }
2586
2587 middleStyle.setResolveParent(style);
2590 showHighlights(annotations, actualStyle);
2591 } else {
2592 Collections.sort(ranges);
2595 Iterator rangesIter = ranges.iterator();
2596 while(rangesIter.hasNext()) {
2597 Range aRange = (Range)rangesIter.next();
2599 if(aRange == range){
2600 rangesIter.remove();
2601 int size = range.end - range.start;
2602 data.subList(range.start, range.end).clear();
2604 while(rangesIter.hasNext()) {
2606 aRange = (Range)rangesIter.next();
2607 aRange.start -= size;
2608 aRange.end -= size;
2609 }
2610 }
2611 }
2612 range = null;
2613 SwingUtilities.invokeLater(new Runnable() {
2614 public void run() {
2615 annotationsTableModel.fireTableDataChanged();
2616 }
2617 });
2618 middleStyle.setResolveParent(textPane.getStyle("default"));
2621 } } }; Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
2625 runnable,
2626 "AnnotationEditor4");
2627 thread.setPriority(Thread.MIN_PRIORITY);
2628 thread.start();
2629 }
2631 public AttributeSet getAttributes() { return style;}
2632
2633 private AttributeSet getActualStyle() { return actualStyle;}
2634
2635 public void setAttributes(AttributeSet newAttributes) {
2636 style.removeAttributes(style.copyAttributes());
2637 style.addAttributes(newAttributes);
2638 }
2639
2640
2641 public void setAnnotations(Set as) {
2642 this.annotations = as;
2643 }
2644
2645 public Set getAnnotations() {
2646 return annotations;
2647 }
2648
2649 public void setNode(DefaultMutableTreeNode node){
2650 this.node = node;
2651 }
2652
2653 public DefaultMutableTreeNode getNode(){
2654 return node;
2655 }
2656
2657 public String toString() {return getTitle();}
2658
2659 private String set;
2660 private String type;
2661 private boolean visible;
2662
2665 private Style style;
2666
2667
2670 private Style middleStyle;
2671
2672
2675 private Style actualStyle;
2676 private Set annotations = null;
2677 private Range range = null;
2678
2679
2680 private DefaultMutableTreeNode node = null;
2681 }
2683
2684
2689 class Range implements Comparable {
2690 public Range(String setName, String type, int start, int end) {
2691 this.setName = setName;
2692 this.type = type;
2693 this.start = start;
2694 this.end = end;
2695 }
2696
2697 public String toString() {
2698 return setName + ", " + type + " (" + start + ", " + end + ")";
2699 }
2700
2701 public int compareTo(Object other) {
2702 if(other instanceof Range) return start - ((Range)other).start;
2703 else throw new ClassCastException("Can't compare a " +
2704 other.getClass() + " to a " +
2705 getClass() + "!");
2706 }
2707
2708 String setName;
2709 String type;
2710 int start;
2711 int end;
2712 }
2714
2715
2719 class EventsHandler implements gate.event.DocumentListener,
2720 AnnotationSetListener{
2721
2722 public void annotationSetAdded(gate.event.DocumentEvent e) {
2723 String setName = e.getAnnotationSetName();
2724 AnnotationSet as = (setName == null ? document.getAnnotations() :
2725 document.getAnnotations(setName));
2726
2727 as.addAnnotationSetListener(this);
2728 if(setName == null) setName = "Default";
2729 TypeData setData = new TypeData(setName, null, false);
2730 setData.setAnnotations(as);
2731
2732 SwingUtilities.invokeLater(new NodeAdder(setData));
2733
2734 ArrayList typesLst = new ArrayList(as.getAllTypes());
2735 Collections.sort(typesLst);
2736
2737 Iterator typesIter = typesLst.iterator();
2738 while(typesIter.hasNext()){
2739 String type = (String)typesIter.next();
2740 TypeData typeData = new TypeData(setName, type, false);
2741 AnnotationSet sameType = as.get(type);
2742 typeData.setAnnotations(sameType);
2743
2744 SwingUtilities.invokeLater(new NodeAdder(typeData));
2745 }
2746 }
2747
2748 public void annotationSetRemoved(gate.event.DocumentEvent e) {
2749 SwingUtilities.invokeLater(
2752 new SetRemovedOperation(e.getAnnotationSetName()));
2753 }
2755
2758 public void contentEdited(DocumentEvent e){
2759 }
2761
2762 public void annotationAdded(AnnotationSetEvent e) {
2763 AnnotationSet set = (AnnotationSet)e.getSource();
2764 String setName = set.getName();
2765 if(setName == null) setName = "Default";
2766 Annotation ann = e.getAnnotation();
2767 String type = ann.getType();
2768 TypeData tData = getTypeData(setName, type);
2769
2770 boolean tableChanged = false;
2771 if(tData != null){
2772 if(tData.getVisible()){
2774 data.add(tData.range.end, ann);
2776 tData.range.end++;
2777 Iterator rangesIter = ranges.
2778 subList(
2779 ranges.indexOf(tData.range) + 1,
2780 ranges.size()).
2781 iterator();
2782 while(rangesIter.hasNext()){
2783 Range aRange = (Range) rangesIter.next();
2784 aRange.start++;
2785 aRange.end++;
2786 } tableChanged = true;
2788
2789 SwingUtilities.invokeLater(
2791 new HihglightsShower(ann,
2792 textPane.getStyle(
2793 "_" + setName + "." +
2794 type + "_")));
2795 } } else {
2797 Map setMap = (Map)typeDataMap.get(setName);
2799 if(setMap == null){
2800 setMap = new HashMap();
2801 typeDataMap.put(setName, setMap);
2802 }
2803 tData = new TypeData(setName, type, false);
2804 tData.setAnnotations(set.get(type));
2805 setMap.put(type, tData);
2806 SwingUtilities.invokeLater(new NodeAdder(tData));
2807
2808 }
2810 if(tableChanged){
2811 SwingUtilities.invokeLater(new Runnable() {
2812 public void run(){
2813 if(annotationsTableModel != null){
2814 annotationsTableModel.fireTableDataChanged();
2815 }
2816 }
2817 });
2818 } }
2821 public void annotationRemoved(AnnotationSetEvent e){
2822 AnnotationSet set = (AnnotationSet)e.getSource();
2823 String setName = set.getName();
2824 if(setName == null) setName = "Default";
2825 Annotation ann = e.getAnnotation();
2826 String type = ann.getType();
2827 TypeData tData = getTypeData(setName, type);
2828 boolean tableChanged = false;
2829
2830 if(tData != null){
2831 if(tData.getVisible()){
2833 data.remove(ann);
2835 tData.range.end--;
2837 Iterator rangesIter = ranges.
2839 subList(ranges.indexOf(tData.range) + 1,
2840 ranges.size()).
2841 iterator();
2842 while(rangesIter.hasNext()){
2843 Range aRange = (Range) rangesIter.next();
2844 aRange.start--;
2845 aRange.end--;
2846 } tableChanged = true;
2848 } SwingUtilities.invokeLater(new HighlightsRemover(ann));
2852
2853 if((tData.annotations.size() == 1 &&
2855 tData.annotations.iterator().next() == ann) ||
2856 tData.annotations.size() == 0){
2857 SwingUtilities.invokeLater(new NodeRemover(tData));
2859 Map setMap = (Map)typeDataMap.get(setName);
2861 setMap.remove(tData.getType());
2862 } }
2865 if(tableChanged){
2866 SwingUtilities.invokeLater(new Runnable() {
2867 public void run(){
2868 if(annotationsTableModel != null){
2869 annotationsTableModel.fireTableDataChanged();
2870 }
2871 }
2872 });
2873 } }
2876
2879 class HighlightsRemover implements Runnable{
2880 HighlightsRemover(Annotation ann){
2881 this.ann = ann;
2882 }
2883 public void run(){
2884 int selStart = textPane.getSelectionStart();
2885 int selEnd = textPane.getSelectionEnd();
2886 textPane.select(ann.getStartNode().getOffset().intValue(),
2887 ann.getEndNode().getOffset().intValue());
2888 textPane.setCharacterAttributes(
2889 textPane.getStyle("default"), true);
2890 textPane.select(selStart, selEnd);
2891 }
2892 Annotation ann;
2893 }
2895
2898 class HihglightsShower implements Runnable{
2899 HihglightsShower(Annotation ann, Style style){
2900 this.ann = ann;
2901 this.style = style;
2902 }
2903 public void run(){
2904 textPane.select(ann.getStartNode().getOffset().intValue(),
2905 ann.getEndNode().getOffset().intValue());
2906 textPane.setCharacterAttributes(style, true);
2907 }
2908 Annotation ann;
2909 Style style;
2910 }
2912
2915 class NodeRemover implements Runnable{
2916 NodeRemover(TypeData tData){
2917 this.tData = tData;
2918 }
2919 public void run(){
2920 DefaultMutableTreeNode node = tData.getNode();
2921 if(node != null){
2922 stylesTreeModel.removeNodeFromParent(tData.getNode());
2923 }else{
2924 Err.prln("Could not find node for " + tData.set + "->" + tData.type);
2925 }
2926 }
2927 TypeData tData;
2928 }
2930
2933 class NodeAdder implements Runnable{
2934 NodeAdder(TypeData tData){
2935 this.tData = tData;
2936 }
2937 public void run(){
2938 DefaultMutableTreeNode newNode =
2940 new DefaultMutableTreeNode(tData, tData.getType() == null);
2941 tData.setNode(newNode);
2942 DefaultMutableTreeNode node = null;
2944 if(tData.getType() == null){
2945 node = (DefaultMutableTreeNode)stylesTreeRoot;
2947 }else{
2949
2951 if(((DefaultMutableTreeNode)stylesTreeRoot).getChildCount() == 0)
2954 return;
2955 node = (DefaultMutableTreeNode)
2956 ((DefaultMutableTreeNode)stylesTreeRoot).getFirstChild();
2957 while(node != null &&
2958 !((TypeData)node.getUserObject()).getSet().equals(tData.getSet()))
2959 node = node.getNextSibling();
2960 }
2961
2962 int i = 0;
2965 if(tData.getType() == null){
2966 while (i < node.getChildCount() &&
2967 ((TypeData)
2968 ((DefaultMutableTreeNode)node.getChildAt(i)).
2969 getUserObject()
2970 ).getSet().compareTo(tData.getSet())<0) i++;
2971 }else{
2972 while (i < node.getChildCount() &&
2973 ((TypeData)
2974 ((DefaultMutableTreeNode)node.getChildAt(i)).
2975 getUserObject()
2976 ).getType().compareTo(tData.getType())<0) i++;
2977 }
2978
2979 stylesTreeModel.insertNodeInto(newNode, node, i);
2981
2982 if(tData.getType() == null){
2983 stylesTree.expandPath(new TreePath(new Object[]{stylesTreeRoot,
2985 newNode}));
2986 }
2987 }
2988
2989 TypeData tData;
2990 }
2992
2996 class SetRemovedOperation implements Runnable{
2997 SetRemovedOperation(String setName){
2998 this.setName = setName;
2999 }
3000
3001 public void run(){
3002 Enumeration setNodesEnum = stylesTreeRoot.children();
3004 DefaultMutableTreeNode setNode = null;
3005 boolean done = false;
3006 while(!done && setNodesEnum.hasMoreElements()){
3007 setNode = (DefaultMutableTreeNode)setNodesEnum.nextElement();
3008 done = ((TypeData)setNode.getUserObject()).getSet().equals(setName);
3009 }
3010
3011 if(!((TypeData)setNode.getUserObject()).getSet().equals(setName)){
3012 throw new GateRuntimeException(
3013 "Could not find the tree node for the " + setName +
3014 " annotation set!");
3015 }
3016
3017 boolean tableChanged = false;
3018 Enumeration typeNodesEnum = setNode.children();
3019 while(typeNodesEnum.hasMoreElements()){
3020 DefaultMutableTreeNode typeNode =
3021 (DefaultMutableTreeNode)typeNodesEnum.nextElement();
3022 TypeData tData = (TypeData)typeNode.getUserObject();
3023 if(tData.getVisible()){
3024 data.subList(tData.range.start, tData.range.end).clear();
3026 int delta = tData.range.end - tData.range.start;
3028 Iterator rangesIter = ranges.
3030 subList(ranges.indexOf(tData.range) + 1,
3031 ranges.size()).
3032 iterator();
3033 while(rangesIter.hasNext()){
3034 Range aRange = (Range) rangesIter.next();
3035 aRange.start -= delta;
3036 aRange.end -= delta;
3037 } ranges.remove(tData.range);
3040 tableChanged = true;
3041
3042
3045 Iterator annIter = tData.getAnnotations().iterator();
3046 while(annIter.hasNext()){
3047 Annotation ann = (Annotation)annIter.next();
3048 new HighlightsRemover(ann).run();
3049 } } }
3053 if(tableChanged){
3054 if(annotationsTableModel != null){
3055 annotationsTableModel.fireTableDataChanged();
3056 }
3057 }
3059 typeDataMap.remove(setName);
3061 stylesTreeModel.removeNodeFromParent(setNode);
3062 }
3064 String setName;
3065 }
3066
3067 }
3069
3073 class SwingDocumentListener implements javax.swing.event.DocumentListener{
3074 public void insertUpdate(final javax.swing.event.DocumentEvent e) {
3075 try{
3076 document.edit(new Long(e.getOffset()), new Long(e.getOffset()),
3077 new DocumentContentImpl(
3078 e.getDocument().getText(e.getOffset(), e.getLength())));
3079 SwingUtilities.invokeLater(new Runnable(){
3080 public void run(){
3081 annotationsTable.repaint();
3082 repairHighlights(e.getOffset(), e.getOffset() + e.getLength());
3083 }
3084 });
3085 updateBlinks();
3086 }catch(BadLocationException ble){
3087 ble.printStackTrace(Err.getPrintWriter());
3088 }catch(InvalidOffsetException ioe){
3089 ioe.printStackTrace(Err.getPrintWriter());
3090 }
3091 }
3092
3093 public void removeUpdate(javax.swing.event.DocumentEvent e) {
3094 try{
3095 document.edit(new Long(e.getOffset()),
3096 new Long(e.getOffset() + e.getLength()),
3097 new DocumentContentImpl(""));
3098 SwingUtilities.invokeLater(new Runnable(){
3099 public void run(){
3100 annotationsTable.repaint();
3101 }
3102 });
3103 updateBlinks();
3104 }catch(InvalidOffsetException ioe){
3105 ioe.printStackTrace(Err.getPrintWriter());
3106 }
3107 }
3108
3109 public void changedUpdate(javax.swing.event.DocumentEvent e) {
3110 }
3112
3115 protected void updateBlinks(){
3116 int[] rows = annotationsTable.getSelectedRows();
3117 if(rows != null && rows.length > 0){
3118 selectionHighlighter.removeAllHighlights();
3119 for(int i = 0; i < rows.length; i++){
3120 int start = ((Long)annotationsTable.getModel().
3121 getValueAt(rows[i], 2)
3122 ).intValue();
3123 int end = ((Long)annotationsTable.getModel().
3124 getValueAt(rows[i], 3)
3125 ).intValue();
3126
3127 start += longLinesCorrection(start);
3129 end += longLinesCorrection(end);
3130
3131 try{
3133 synchronized (selectionHighlighter){
3134 selectionHighlighter.addHighlight(start, end,
3135 DefaultHighlighter.DefaultPainter);
3136 }
3137 }catch(BadLocationException ble){
3138 throw new GateRuntimeException(ble.toString());
3139 }
3140 }
3142 }
3147
3148 }
3149 }
3151
3155 class SelectionBlinker implements Runnable{
3156 public void run(){
3157 synchronized(selectionHighlighter){
3158 highlights = selectionHighlighter.getHighlights();
3159 }
3160
3161
3162 while(highlights != null && highlights.length > 0){
3163 SwingUtilities.invokeLater(new Runnable(){
3164 public void run(){
3165 showHighlights();
3166 }
3167 });
3168 try{
3169 Thread.sleep(400);
3170 }catch(InterruptedException ie){
3171 ie.printStackTrace(Err.getPrintWriter());
3172 }
3173 SwingUtilities.invokeLater(new Runnable(){
3174 public void run(){
3175 hideHighlights();
3176 }
3177 });
3178
3179 try{
3180 Thread.sleep(600);
3181 }catch(InterruptedException ie){
3182 ie.printStackTrace(Err.getPrintWriter());
3183 }
3184 synchronized(selectionHighlighter){
3185 highlights = selectionHighlighter.getHighlights();
3186 }
3187 } synchronized(selectionHighlighter){
3190 thread = null;
3191 }
3192 }
3194
3198 public synchronized void testAndStart(){
3199 synchronized(selectionHighlighter){
3200 if(thread == null){
3201 thread = new Thread(Thread.currentThread().getThreadGroup(),
3202 this, "AnnotationEditor2");
3203 thread.setPriority(Thread.MIN_PRIORITY);
3204 thread.start();
3205 }
3206 }
3207 }
3208
3209 protected void showHighlights(){
3210 actualHighlights.clear();
3211 try{
3212 for(int i = 0; i < highlights.length; i++){
3213 actualHighlights.add(highlighter.addHighlight(
3214 highlights[i].getStartOffset(),
3215 highlights[i].getEndOffset(),
3216 highlights[i].getPainter()));
3217 }
3218 }catch(BadLocationException ble){
3219 ble.printStackTrace(Err.getPrintWriter());
3220 }
3221 }
3222
3223 protected void hideHighlights(){
3224 Iterator hIter = actualHighlights.iterator();
3225 while(hIter.hasNext()) highlighter.removeHighlight(hIter.next());
3226 }
3227
3228 ArrayList actualHighlights = new ArrayList();
3229 Thread thread;
3230 Highlighter.Highlight[] highlights;
3231 }
3233
3241 public class CustomLabelView extends javax.swing.text.LabelView {
3242 public CustomLabelView(Element elem) {
3243 super(elem);
3244 }
3245
3246 public Color getBackground() {
3247 AttributeSet attr = getAttributes();
3248 if (attr != null) {
3249 javax.swing.text.Document d = super.getDocument();
3250 if (d instanceof StyledDocument){
3251 StyledDocument doc = (StyledDocument) d;
3252 return doc.getBackground(attr);
3253 }else{
3254 return null;
3255 }
3256 }
3257 return null;
3258 }
3259 }
3260
3261
3266 protected class HighlightAnnotationMenu extends JMenu {
3267 public HighlightAnnotationMenu(Annotation ann, AnnotationSet aSet) {
3268 super(ann.getType());
3269 setToolTipText("<html><b>Features:</b><br>" +
3270 (ann.getFeatures() == null ? "" :
3271 ann.getFeatures().toString()) + "</html>");
3272 this.annotation = ann;
3273 this.set = aSet;
3274 this.setName = (set.getName() == null) ? "Default" : set.getName();
3275 start = ann.getStartNode().getOffset().intValue();
3276 end = ann.getEndNode().getOffset().intValue();
3277 this.addMouseListener(new MouseAdapter() {
3278 public void mouseEntered(MouseEvent e) {
3279 try {
3280 highlight = highlighter.addHighlight(start, end,
3281 DefaultHighlighter.DefaultPainter);
3282 }catch(BadLocationException ble){
3283 throw new GateRuntimeException(ble.toString());
3284 }
3285 }
3286
3287 public void mouseExited(MouseEvent e) {
3288 if(highlight != null){
3289 highlighter.removeHighlight(highlight);
3290 highlight = null;
3291 }
3292 }
3293 });
3294
3295 this.add(new AbstractAction(){
3296 {
3297 putValue(NAME, "Select");
3298 }
3299 public void actionPerformed(ActionEvent e) {
3300 Runnable runnable = new Runnable(){
3301 public void run(){
3302 if(highlight != null){
3303 highlighter.removeHighlight(highlight);
3304 highlight = null;
3305 }
3306 selectAnnotation(setName, annotation);
3307 }
3308 };
3309 Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
3310 runnable,
3311 "AnnotationEditor5");
3312 thread.start();
3313 }
3314 });
3315
3316 this.add(new AbstractAction(){
3317 {
3318 putValue(NAME, "Delete");
3319 }
3320 public void actionPerformed(ActionEvent e) {
3321 Runnable runnable = new Runnable(){
3322 public void run(){
3323 if(highlight != null){
3324 highlighter.removeHighlight(highlight);
3325 highlight = null;
3326 }
3327 set.remove(annotation);
3328 }
3329 };
3330 Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
3331 runnable,
3332 "AnnotationEditor5");
3333 thread.start();
3334 }
3335 });
3336
3337 }
3338
3339 int start;
3340 int end;
3341 AnnotationSet set;
3342 String setName;
3343 Annotation annotation;
3344 Object highlight;
3345 }
3346
3347
3348 protected class DeleteSelectedAnnotationsAction extends AbstractAction {
3349 public DeleteSelectedAnnotationsAction(JComponent source){
3350 super("Delete selected annotations");
3351 this.source = source;
3352 }
3353
3354 public void actionPerformed(ActionEvent evt){
3355 if(source == annotationsTable){
3356 Map annotationsBySet = new HashMap();
3359 int[] rows = annotationsTable.getSelectedRows();
3360 String setName;
3361 for(int i = 0; i < rows.length; i++){
3362 int row = rows[i];
3363 Annotation ann = (Annotation)annotationsTable.
3365 getModel().getValueAt(row, -1);
3366 setName = (String)annotationsTable.getModel().
3368 getValueAt(row, 1);
3369 java.util.List existingList = (java.util.List)
3370 annotationsBySet.get(setName);
3371 if(existingList == null){
3372 existingList = new ArrayList();
3373 annotationsBySet.put(setName, existingList);
3374 }
3375 existingList.add(ann);
3376 } Iterator setsIter = annotationsBySet.keySet().iterator();
3379 while(setsIter.hasNext()){
3380 setName = (String)setsIter.next();
3381 AnnotationSet set = setName.equals("Default")?
3382 document.getAnnotations() :
3383 document.getAnnotations(setName);
3384 set.removeAll((java.util.List)annotationsBySet.get(setName));
3385 } }else if(source == stylesTree){
3387 TreePath[] paths = stylesTree.getSelectionPaths();
3388 for(int i = 0; i < paths.length; i++){
3389 TypeData tData = (TypeData)((DefaultMutableTreeNode)
3390 paths[i].getLastPathComponent()).getUserObject();
3391 String setName = tData.getSet();
3392 if(tData.getType() == null){
3393 if(setName.equals("Default")){
3395 JOptionPane.showMessageDialog(
3396 DocumentEditor.this,
3397 "The default annotation set cannot be deleted!\n" +
3398 "It will only be cleared...",
3399 "GATE", JOptionPane.ERROR_MESSAGE);
3400 document.getAnnotations().clear();
3401 }else{
3402 document.removeAnnotationSet(setName);
3403 }
3404 }else{
3405 if(!setName.equals("Default") &&
3407 !document.getNamedAnnotationSets().containsKey(setName)){
3408 return;
3411 }
3412 AnnotationSet set = setName.equals("Default") ?
3413 document.getAnnotations() :
3414 document.getAnnotations(setName);
3415 if(set != null){
3416 AnnotationSet subset = set.get(tData.getType());
3417 if(subset != null) set.removeAll(new ArrayList(subset));
3418 } } } }else if(source == corefTree){
3422 TreePath[] paths = corefTree.getSelectionPaths();
3423 for(int i = 0; i < paths.length; i++){
3424 CorefData cData = (CorefData)((DefaultMutableTreeNode)
3425 paths[i].getLastPathComponent()).getUserObject();
3426 class CorefClearer implements Runnable{
3427 CorefClearer(CorefData cData){
3428 this.cData = cData;
3429 }
3430 public void run(){
3431 cData.removeAnnotations();
3432 }
3433 CorefData cData;
3434 }
3435 Thread thread = new Thread(new CorefClearer(cData));
3436 thread.setPriority(Thread.MIN_PRIORITY);
3437 thread.start();
3438 }
3439 }
3440 } JComponent source;
3442 }
3444 protected class SearchAction extends AbstractAction {
3445 public SearchAction(){
3446 super("Search");
3447 putValue(SHORT_DESCRIPTION, "Search within the text");
3448 putValue(SMALL_ICON, MainFrame.getIcon("search.gif"));
3449 }
3450
3451 public void actionPerformed(ActionEvent evt){
3452 if(searchDialog == null){
3453 Window parent = SwingUtilities.getWindowAncestor(DocumentEditor.this);
3454 searchDialog = (parent instanceof Dialog) ?
3455 new SearchDialog((Dialog)parent) :
3456 new SearchDialog((Frame)parent);
3457 searchDialog.pack();
3458 searchDialog.setLocationRelativeTo(DocumentEditor.this);
3459 searchDialog.setResizable(false);
3460 MainFrame.getGuiRoots().add(searchDialog);
3461 }
3462
3463 if(searchDialog.isVisible()){
3464 searchDialog.toFront();
3465 }else{
3466 searchDialog.setVisible(true);
3467 }
3468 }
3469 }
3470
3471 protected class SearchDialog extends JDialog{
3472 SearchDialog(Frame owner){
3473 super(owner, false);
3474 setTitle( "Find in \"" + document.getName() + "\"");
3475 initLocalData();
3476 initGuiComponents();
3477 initListeners();
3478 }
3479
3480 SearchDialog(Dialog owner){
3481 super(owner, false);
3482 setTitle("Find in \"" + document.getName() + "\"");
3483 initLocalData();
3484 initGuiComponents();
3485 initListeners();
3486 }
3487 protected void initLocalData(){
3488 pattern = null;
3489 nextMatchStartsFrom = 0;
3490 content = document.getContent().toString();
3491
3492 findFirstAction = new AbstractAction("Find first"){
3493 {
3494 putValue(SHORT_DESCRIPTION, "Finds first match");
3495 }
3496
3497 public void actionPerformed(ActionEvent evt){
3498 refresh();
3500 textPane.setCaretPosition(textPane.getCaretPosition());
3502 boolean found = false;
3503 int start = nextMatchStartsFrom - 1;
3504 int end = -1;
3505
3506 Matcher matcher = pattern.matcher(content);
3507 while (matcher.find() && (found == false))
3508 {
3509 start = matcher.start();
3510 end = matcher.end();
3511 if (wholeWordsChk.isSelected())
3512 {
3513 found = (start == 0 || !Character.isLetterOrDigit(content.charAt(start - 1)))
3515 && (end == content.length() || !Character.isLetterOrDigit(content.charAt(end)));
3516 }
3517 else
3518 found = true;
3519 }
3520
3521 if (found)
3522 {
3523 nextMatchStartsFrom = start + 1;
3524 SwingUtilities.getWindowAncestor(textPane).requestFocus();
3526 textPane.requestFocus();
3527 textPane.setCaretPosition(start);
3528 textPane.moveCaretPosition(end);
3529 }
3530 else
3531 {
3532 JOptionPane.showMessageDialog(searchDialog, "String not found!", "GATE", JOptionPane.INFORMATION_MESSAGE);
3533 }
3534 }
3535 };
3536
3537
3538 findNextAction = new AbstractAction("Find next"){
3539 {
3540 putValue(SHORT_DESCRIPTION, "Finds next match");
3541 }
3542 public void actionPerformed(ActionEvent evt){
3543 refresh();
3545 textPane.setCaretPosition(textPane.getCaretPosition());
3547 boolean found = false;
3548 int start = nextMatchStartsFrom - 1;
3549 int end = -1;
3550
3551 Matcher matcher = pattern.matcher(content);
3552 while (matcher.find() && (found == false))
3553 {
3554 start = matcher.start();
3555 end = matcher.end();
3556 if (wholeWordsChk.isSelected())
3557 {
3558 found = (start == 0 || !Character.isLetterOrDigit(content.charAt(start - 1)))
3560 && (end == content.length() || !Character.isLetterOrDigit(content.charAt(end)));
3561 }
3562 else
3563 found = true;
3564 }
3565
3566 if (found)
3567 {
3568 nextMatchStartsFrom = start + 1;
3569 SwingUtilities.getWindowAncestor(textPane).requestFocus();
3571 textPane.requestFocus();
3572 textPane.setCaretPosition(start);
3573 textPane.moveCaretPosition(end);
3574 }
3575 else
3576 {
3577 JOptionPane.showMessageDialog(searchDialog, "String not found!", "GATE", JOptionPane.INFORMATION_MESSAGE);
3578 }
3579 }
3580 };
3581
3582 cancelAction = new AbstractAction("Cancel"){
3583 {
3584 putValue(SHORT_DESCRIPTION, "Cancel");
3585 }
3586 public void actionPerformed(ActionEvent evt){
3587 searchDialog.setVisible(false);
3588 }
3589 };
3590
3591 }
3592
3593
3594 protected void initGuiComponents(){
3595 getContentPane().setLayout(new BoxLayout(getContentPane(),
3596 BoxLayout.Y_AXIS));
3597
3598 getContentPane().add(Box.createVerticalStrut(5));
3599 Box hBox = Box.createHorizontalBox();
3600 hBox.add(Box.createHorizontalStrut(5));
3601 hBox.add(new JLabel("Find what:"));
3602 hBox.add(Box.createHorizontalStrut(5));
3603 hBox.add(patternTextField = new JTextField(20));
3604 hBox.add(Box.createHorizontalStrut(5));
3605 hBox.add(Box.createHorizontalGlue());
3606 getContentPane().add(hBox);
3607
3608 getContentPane().add(Box.createVerticalStrut(5));
3609 hBox = Box.createHorizontalBox();
3610 hBox.add(Box.createHorizontalStrut(5));
3611 hBox.add(ignoreCaseChk = new JCheckBox("Ignore case", false));
3612 hBox.add(Box.createHorizontalStrut(5));
3613 hBox.add(wholeWordsChk = new JCheckBox("Whole words only", false));
3614 hBox.add(Box.createHorizontalStrut(5));
3615 hBox.add(Box.createHorizontalGlue());
3616 getContentPane().add(hBox);
3617
3618 getContentPane().add(Box.createVerticalStrut(5));
3619 hBox = Box.createHorizontalBox();
3620 hBox.add(Box.createHorizontalGlue());
3621 hBox.add(new JButton(findFirstAction));
3622 hBox.add(Box.createHorizontalStrut(5));
3623 hBox.add(new JButton(findNextAction));
3624 hBox.add(Box.createHorizontalStrut(5));
3625 hBox.add(new JButton(cancelAction));
3626 hBox.add(Box.createHorizontalGlue());
3627 getContentPane().add(hBox);
3628 getContentPane().add(Box.createVerticalStrut(5));
3629 }
3630
3631 protected void initListeners(){
3632 addComponentListener(new ComponentAdapter() {
3633 public void componentHidden(ComponentEvent e) {
3634 }
3635
3636 public void componentMoved(ComponentEvent e) {
3637 }
3638
3639 public void componentResized(ComponentEvent e) {
3640 }
3641
3642 public void componentShown(ComponentEvent e) {
3643 refresh();
3644 }
3645 });
3646
3647 patternTextField.getDocument().addDocumentListener(
3648 new javax.swing.event.DocumentListener() {
3649 public void insertUpdate(javax.swing.event.DocumentEvent e) {
3650 refresh();
3651 }
3652
3653 public void removeUpdate(javax.swing.event.DocumentEvent e) {
3654 refresh();
3655 }
3656
3657 public void changedUpdate(javax.swing.event.DocumentEvent e) {
3658 refresh();
3659 }
3660 });
3661
3662 }
3663
3664 protected void refresh(){
3665 String patternText = patternTextField.getText();
3666 if(patternText != null && patternText.length() > 0){
3667 findFirstAction.setEnabled(true);
3669 findNextAction.setEnabled(true);
3670
3671 try
3673 {
3674 pattern = ignoreCaseChk.isSelected() ? Pattern.compile(patternText, Pattern.CASE_INSENSITIVE) : Pattern
3675 .compile(patternText);
3676 }
3677 catch (Exception ree)
3678 {
3679 JOptionPane.showMessageDialog(searchDialog, "Invalid pattern!\n" + ree.toString(), "GATE", JOptionPane.ERROR_MESSAGE);
3680 }
3681 }else{
3682 findFirstAction.setEnabled(false);
3683 findNextAction.setEnabled(false);
3684 }
3685
3686 if(pattern == null){
3687 }
3688 }
3689 JTextField patternTextField;
3690 JCheckBox ignoreCaseChk;
3691 JCheckBox wholeWordsChk;
3692 Pattern pattern;
3693 int nextMatchStartsFrom;
3694 String content;
3695
3696 Action findFirstAction;
3697 Action findNextAction;
3698 Action cancelAction;
3699 }
3700
3701 protected class PrintAction extends AbstractAction{
3702 public PrintAction(){
3703 super("Print");
3704 }
3705
3706 public void actionPerformed(ActionEvent e){
3707 Runnable runnable = new Runnable(){
3708 public void run(){
3709 PrinterJob printerJob = PrinterJob.getPrinterJob();
3710
3711 if (printerJob.printDialog()) {
3712 try{
3713
3714 PageFormat pageFormat = printerJob.defaultPage();
3716 Pageable pageable = new JComponentPrinter(textPane, pageFormat);
3717 printerJob.setPageable(pageable);
3718
3719 printerJob.print();
3720 StatusListener sListener = (StatusListener)MainFrame.
3722 getListeners().
3723 get("gate.event.StatusListener");
3724 if(sListener != null){
3725 sListener.statusChanged("Document printed!");
3726 }
3727
3728 }catch(Exception ex) {
3729 ex.printStackTrace();
3730 }
3731 }
3732 }
3733 };
3734
3735 Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
3736 runnable, "Print thread");
3737 thread.setPriority(Thread.MIN_PRIORITY);
3738 thread.start();
3739 }
3740 }
3741
3742
3743
3747 protected class EditAnnotationAction extends AbstractAction {
3748 public EditAnnotationAction(AnnotationSet set, Annotation annotation){
3749 super("Edit");
3750 this.set = set;
3751 this.annotation = annotation;
3752 putValue(SHORT_DESCRIPTION, "Edits the annotation");
3753 }
3754
3755 public void actionPerformed(ActionEvent e){
3756 java.util.List specificEditors = Gate.getCreoleRegister().
3758 getAnnotationVRs(annotation.getType());
3759 java.util.List genericEditors = Gate.getCreoleRegister().
3760 getAnnotationVRs();
3761 JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.BOTTOM);
3763 Iterator editorIter = specificEditors.iterator();
3765 while(editorIter.hasNext()){
3766 String editorType = (String)editorIter.next();
3767 AnnotationVisualResource editor;
3769 try{
3770 editor = (AnnotationVisualResource)
3771 Factory.createResource(editorType);
3772 if(editor instanceof ResizableVisualResource){
3773 tabbedPane.add((Component)editor,
3774 ((ResourceData)Gate.getCreoleRegister().
3775 get(editorType)).getName());
3776 }else{
3777 JScrollPane scroller = new JScrollPane((Component)editor);
3778 tabbedPane.add(scroller,
3780 ((ResourceData)Gate.getCreoleRegister().
3781 get(editorType)).getName());
3782 }
3783
3784
3785 editor.setTarget(set);
3786 editor.setAnnotation(annotation);
3787 }catch(ResourceInstantiationException rie){
3788 rie.printStackTrace(Err.getPrintWriter());
3789 }
3790 }
3791
3792 editorIter = genericEditors.iterator();
3794 while(editorIter.hasNext()){
3795 String editorType = (String)editorIter.next();
3796 AnnotationVisualResource editor;
3798 try{
3799 editor = (AnnotationVisualResource)
3800 Factory.createResource(editorType);
3801 if(editor.canDisplayAnnotationType(annotation.getType())){
3802 editor.setTarget(set);
3803 editor.setAnnotation(annotation);
3804 if(editor instanceof ResizableVisualResource){
3805 tabbedPane.add((Component)editor,
3806 ((ResourceData)Gate.getCreoleRegister().
3807 get(editorType)).getName());
3808 }else{
3809 tabbedPane.add(new JScrollPane((Component)editor),
3810 ((ResourceData)Gate.getCreoleRegister().
3811 get(editorType)).getName());
3812 }
3813 }
3814 }catch(ResourceInstantiationException rie){
3815 rie.printStackTrace(Err.getPrintWriter());
3816 }
3817
3818 }
3819
3820 boolean allOK = false;
3822 while(!allOK){
3823 if(OkCancelDialog.showDialog(DocumentEditor.this,
3824 tabbedPane,
3825 "Edit Annotation")){
3826 try{
3827 Component comp = tabbedPane.getSelectedComponent();
3828 if(comp instanceof AnnotationVisualResource){
3829 ((AnnotationVisualResource)comp).okAction();
3830 }else if(comp instanceof JScrollPane){
3831 ((AnnotationVisualResource)((JScrollPane)comp).
3832 getViewport().getView()).okAction();
3833 }else{
3834 throw new LuckyException("DocumentEditor.EditAnnotationAction1");
3835 }
3836
3837 allOK = true;
3838 }catch(GateException ge){
3839 JOptionPane.showMessageDialog(
3840 DocumentEditor.this,
3841 "There was an error:\n" +
3842 ge.toString(),
3843 "GATE", JOptionPane.ERROR_MESSAGE);
3844 ge.printStackTrace(Err.getPrintWriter());
3845 allOK = false;
3846 }
3847 }else{
3848 if (OkCancelDialog.userHasPressedCancel)
3849 try{
3850 Component comp = tabbedPane.getSelectedComponent();
3851 if(comp instanceof AnnotationVisualResource){
3852 ((AnnotationVisualResource)comp).cancelAction();
3853 }else if(comp instanceof JScrollPane){
3854 ((AnnotationVisualResource)
3855 ((JScrollPane)comp).getViewport().getView()).cancelAction();
3856 }else{
3857 throw new LuckyException("DocumentEditor.EditAnnotationAction");
3858 }
3859 allOK = true;
3860 } catch(GateException ge){
3861 JOptionPane.showMessageDialog(
3862 DocumentEditor.this,
3863 "There was an error:\n" +
3864 ge.toString(),
3865 "GATE", JOptionPane.ERROR_MESSAGE);
3866 allOK = false;
3867 }
3868 allOK = true;
3869 }
3870 } }
3873 protected AnnotationSet set;
3874 protected Annotation annotation;
3875 }
3877
3881 class NewAnnotationAction extends AbstractAction{
3882 public NewAnnotationAction(AnnotationSet set,
3883 Long startOffset,
3884 Long endOffset){
3885 super("New annotation");
3886 putValue(SHORT_DESCRIPTION, "Creates a new annotation");
3887 this.set = set;
3888 this.startOffset = startOffset;
3889 this.endOffset = endOffset;
3890 this.type = null;
3891 }
3892
3893 public NewAnnotationAction(AnnotationSet set, String type,
3894 Long startOffset, Long endOffset){
3895 super("New \"" + type + "\" annotation");
3896 putValue(SHORT_DESCRIPTION, "Creates a new annotation of type \"" +
3897 type + "\"");
3898 this.set = set;
3899 this.startOffset = startOffset;
3900 this.endOffset = endOffset;
3901 this.type = type;
3902 }
3903
3904 public void actionPerformed(ActionEvent e){
3905 if(set == null){
3906 String setName = JOptionPane.showInputDialog(
3908 DocumentEditor.this,
3909 "Please provide a name for the new annotation set",
3910 "GATE", JOptionPane.QUESTION_MESSAGE);
3911 if(setName == null) return;
3912 this.set = document.getAnnotations(setName);
3913 }
3914 java.util.List specificEditors;
3916 if(type != null) specificEditors = Gate.getCreoleRegister().
3917 getAnnotationVRs(type);
3918 else specificEditors = new ArrayList();
3919
3920 java.util.List genericEditors = Gate.getCreoleRegister().
3921 getAnnotationVRs();
3922 JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.BOTTOM);
3924 Iterator editorIter = specificEditors.iterator();
3926 while(editorIter.hasNext()){
3927 String editorType = (String)editorIter.next();
3928 AnnotationVisualResource editor;
3930 try{
3931 editor = (AnnotationVisualResource)
3932 Factory.createResource(editorType);
3933 tabbedPane.add(new JScrollPane((Component)editor),
3934 ((ResourceData)Gate.getCreoleRegister().get(editorType)).
3935 getName());
3936 editor.setTarget(set);
3937 editor.setSpan(startOffset, endOffset, type);
3938
3939 }catch(ResourceInstantiationException rie){
3940 rie.printStackTrace(Err.getPrintWriter());
3941 }
3942 }
3943
3944 editorIter = genericEditors.iterator();
3946 while(editorIter.hasNext()){
3947 String editorType = (String)editorIter.next();
3948 AnnotationVisualResource editor;
3950 try{
3951 editor = (AnnotationVisualResource)
3952 Factory.createResource(editorType);
3953
3954 if(type == null ||
3955 (type != null && editor.canDisplayAnnotationType(type))){
3956 editor.setTarget(set);
3957 editor.setSpan(startOffset, endOffset, type);
3958 tabbedPane.add(new JScrollPane((Component)editor),
3959 ((ResourceData)Gate.getCreoleRegister().
3960 get(editorType)).getName());
3961 }
3962 }catch(ResourceInstantiationException rie){
3963 rie.printStackTrace(Err.getPrintWriter());
3964 }
3965
3966 }
3967
3968 boolean allOK = false;
3970 while(!allOK){
3971 if(OkCancelDialog.showDialog(DocumentEditor.this,
3972 tabbedPane, "Edit Annotation")){
3973 try{
3974 ((AnnotationVisualResource)((JScrollPane)tabbedPane.
3975 getSelectedComponent()).getViewport().
3976 getView()
3977 ).okAction();
3978 allOK = true;
3979 }catch(GateException ge){
3980 JOptionPane.showMessageDialog(
3981 DocumentEditor.this,
3982 "There was an error:\n" +
3983 ge.toString(),
3984 "GATE", JOptionPane.ERROR_MESSAGE);
3985 allOK = false;
3987 }
3988 }else{
3989 allOK = true;
3990 }
3991 }
3993
3994 }
3996 AnnotationSet set;
3997 Long startOffset;
3998 Long endOffset;
3999 String type;
4000 }
4002
4010 public class CustomStyledEditorKit extends StyledEditorKit{
4011 private final ViewFactory defaultFactory = new CustomStyledViewFactory();
4012 public ViewFactory getViewFactory() {
4013 return defaultFactory;
4014 }
4015
4016
4023 public void read(Reader in, javax.swing.text.Document doc, int pos)
4024 throws IOException, BadLocationException {
4025
4026 char[] buff = new char[65536];
4027 int charsRead = 0;
4028 while ((charsRead = in.read(buff, 0, buff.length)) != -1) {
4029 doc.insertString(pos, new String(buff, 0, charsRead), null);
4030 pos += charsRead;
4031 } } }
4034
4035
4043 public class CustomStyledViewFactory implements ViewFactory{
4044 public View create(Element elem) {
4045 String kind = elem.getName();
4046 if (kind != null) {
4047 if (kind.equals(AbstractDocument.ContentElementName)) {
4048 return new CustomLabelView(elem);
4049 }else if (kind.equals(AbstractDocument.ParagraphElementName)) {
4050 return new ParagraphView(elem);
4051 }else if (kind.equals(AbstractDocument.SectionElementName)) {
4052 return new BoxView(elem, View.Y_AXIS);
4053 }else if (kind.equals(StyleConstants.ComponentElementName)) {
4054 return new ComponentView(elem);
4055 }else if (kind.equals(StyleConstants.IconElementName)) {
4056 return new IconView(elem);
4057 }
4058 }
4059 return new CustomLabelView(elem);
4061 }
4062 }
4063 }