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