1
15
16 package gate.gui;
17
18 import java.awt.*;
20 import java.awt.event.*;
21 import java.beans.PropertyChangeEvent;
22 import java.util.*;
23
24 import javax.swing.*;
25
26 import gate.*;
27 import gate.creole.*;
28 import gate.util.*;
29
30
31
119
120 public class SyntaxTreeViewer extends AbstractVisualResource
121 implements Scrollable, ActionListener, MouseListener,
122 AnnotationVisualResource {
123
124
125 public static final String TREE_NODE_ANNOTATION_TYPE = "SyntaxTreeNode";
126
127 public static final String NODE_CAT_FEATURE_NAME = "cat";
128
129 public static final String NODE_CONSISTS_FEATURE_NAME = "consists";
130
131 protected boolean laidOut = false;
134
135 protected int horizButtonGap = 5;
137
138 protected int vertButtonGap = 50;
140
141 protected int extraButtonWidth = 10;
143
144 protected int maxUnitIncrement = 10;
146
147 BorderLayout borderLayout1 = new BorderLayout();
149 JPopupMenu popup = new JPopupMenu(); Color buttonBackground;
151 Color selectedNodeColor = Color.red.darker();
152
153 HashSet lines = new HashSet();
155
156 protected Annotation utterance;
160 protected Long utteranceStartOffset = new Long(0);
161 protected Long utteranceEndOffset = new Long(0);
162 protected AnnotationSet currentSet = null;
163
164 protected String tokenType = ANNIEConstants.TOKEN_ANNOTATION_TYPE;
165
166 protected String displayedString = "";
168
169 protected String treeNodeAnnotationType = TREE_NODE_ANNOTATION_TYPE;
173
174 protected String textAnnotationType = ANNIEConstants.SENTENCE_ANNOTATION_TYPE;
180
181 protected HashMap leaves = new HashMap();
183
184 protected HashMap nonTerminals = new HashMap();
186
187 protected HashMap buttons = new HashMap();
189
190 protected Vector selection = new Vector();
192
193 protected AnnotationSet treeAnnotations;
195
196 protected Document document = null;
197
199 protected boolean utteranceAdded = false;
202
203
204 public SyntaxTreeViewer() {
205 try {
206 jbInit();
207 }
208 catch(Exception ex) {
209 ex.printStackTrace(Err.getPrintWriter());
210 }
211
212 }
213
214 private SyntaxTreeViewer(String annotType) {
216
217 treeNodeAnnotationType = annotType;
218 try {
219 jbInit();
220 }
221 catch(Exception ex) {
222 ex.printStackTrace(Err.getPrintWriter());
223 }
224 }
225
226 private void jbInit() throws Exception {
228
229 if (laidOut)
231 this.setLayout(borderLayout1);
232 else
233 this.setLayout(null);
234
235 this.setPreferredSize(new Dimension (600, 400));
236 this.setSize(600, 400);
237 this.setBounds(0, 0, 600, 400);
238 this.addComponentListener(new java.awt.event.ComponentAdapter() {
239 public void componentShown(ComponentEvent e) {
240 this_componentShown(e);
241 }
242 public void componentHidden(ComponentEvent e) {
243 this_componentHidden(e);
244 }
245 });
246 this.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
247
248 public void propertyChange(PropertyChangeEvent e) {
249 this_propertyChange(e);
250 }
251 });
252
253 buttonBackground = Color.red;
255 fillCategoriesMenu();
257
258
260 this.add(popup);
262 }
264
266
271
272 public void setTarget(Object target) {
273 if (target == null) return;
274 currentSet = (AnnotationSet) target;
275 document = currentSet.getDocument();
276 }
277
278
283 public void setAnnotation(Annotation ann){
284 if (ann == null) return;
285
286 utterance = ann;
287 utteranceStartOffset = utterance.getStartNode().getOffset();
288 utteranceEndOffset = utterance.getEndNode().getOffset();
289 textAnnotationType = ann.getType();
290
291 clearAll();
292 utterances2Trees();
293 annotations2Trees();
294 this.setVisible(true);
295 repaint();
296 }
297
298
305 public void setSpan(Long startOffset, Long endOffset, String annotType){
306 if (startOffset == null || endOffset == null) return;
308 if (document == null) return;
309
310 try {
311 Integer newId = currentSet.add( startOffset, endOffset, annotType,
312 Factory.newFeatureMap());
313 utterance = currentSet.get(newId);
314 utteranceAdded = true;
315 textAnnotationType = annotType;
316 setAnnotation(utterance);
317
318 } catch (InvalidOffsetException ioe) {
319 ioe.printStackTrace(Err.getPrintWriter());
320 }
321
322 }
323
324
328 public void okAction() throws GateException{
329 STreeNode.transferAnnotations(document, currentSet);
332
333 }
335
339 public void cancelAction() throws GateException{
340 if (utteranceAdded) {
342 currentSet.remove(utterance); utteranceAdded = false;
344 }
345 STreeNode.undo(document);
348
349 }
351
352
359 public boolean canDisplayAnnotationType(String annotationType){
360 if (annotationType == null) return false;
363 boolean found = false;
364
365 java.util.List specificEditors = Gate.getCreoleRegister().
366 getAnnotationVRs(annotationType);
367 Iterator editorIter = specificEditors.iterator();
368 while(editorIter.hasNext() && !found){
369 String editorClass = (String)editorIter.next();
370
371 Out.println(editorClass);
372 if (editorClass.indexOf(this.getClass().getName()) > -1) {
373 textAnnotationType = annotationType;
374 found = true;
375 }
376 }
377
378 return found;
379 }
381
382
436
447
448
452
467
468
477
478 protected void paintComponent(Graphics g) {
479 super.paintComponent( g);
480 drawLines(g);
481 }
483
484 private void drawLines(Graphics g) {
485
486 for (Iterator i = lines.iterator(); i.hasNext(); ) {
487 Coordinates coords = (Coordinates) i.next();
488
489 g.drawLine( coords.getX1(),
490 coords.getY1(),
491 coords.getX2(),
492 coords.getY2());
493 } }
496 public Dimension getPreferredScrollableViewportSize() {
497 return getPreferredSize();
498 }
500 public int getScrollableUnitIncrement(Rectangle visibleRect,
501 int orientation, int direction) {
502 return maxUnitIncrement;
503 }
505 public int getScrollableBlockIncrement(Rectangle visibleRect,
506 int orientation, int direction) {
507 if (orientation == SwingConstants.HORIZONTAL)
508 return visibleRect.width - maxUnitIncrement;
509 else
510 return visibleRect.height - maxUnitIncrement;
511 }
513 public boolean getScrollableTracksViewportWidth() {
514 return false;
515 }
517 public boolean getScrollableTracksViewportHeight() {
518 return false;
519 }
520
521 void this_propertyChange(PropertyChangeEvent e) {
522
523 if (e.getPropertyName().equals("utterance")) {
525 clearAll();
526 utterances2Trees();
527 }
528
529 }
531
535 private void clearAll() {
536 lines.clear();
537 this.removeAll();
538 buttons.clear();
539 leaves.clear();
540 nonTerminals.clear();
541 }
542
543
546 private void annotations2Trees() {
547 if (document == null) return;
548
549 HashMap processed = new HashMap();
551 AnnotationSet tempSet = currentSet.get(treeNodeAnnotationType);
553 if (tempSet == null || tempSet.isEmpty())
554 return;
555 treeAnnotations = tempSet.get(utterance.getStartNode().getOffset(),
556 utterance.getEndNode().getOffset());
557 if (treeAnnotations == null || treeAnnotations.isEmpty())
558 return;
559
560 java.util.List nodeAnnots = new ArrayList(treeAnnotations);
564 Collections.sort(nodeAnnots, new gate.util.OffsetComparator());
565
566 Vector childrenButtons = new Vector();
567 String oldParent = "";
568
569 Iterator i = nodeAnnots.iterator();
571 while (i.hasNext()) {
572 Annotation annot = (Annotation) i.next();
573
574 java.util.List children =
575 (java.util.List) annot.getFeatures().get(NODE_CONSISTS_FEATURE_NAME);
576 if (children == null ||
578 children.isEmpty())
579 {
580
581 STreeNode leaf = findLeaf(annot.getStartNode(), annot.getEndNode());
582 if (leaf == null) { Out.println("Can't find my leaf node for annotation: " + annot);
584 }
585
586 JButton button = (JButton) buttons.get(new Integer(leaf.getID()));
587 selection.clear();
588 selection.add(button);
589
590 STreeNode node = new STreeNode(annot);
592 node.add(leaf);
593 node.setLevel(1);
594 node.setUserObject(annot.getFeatures().get(NODE_CAT_FEATURE_NAME));
595 nonTerminals.put(new Integer(node.getID()), node);
596 JButton parentButton = createCentralButton(node);
597 addLines(node);
598
599 processed.put(annot.getId(), parentButton);
601
602 }
604 }
606 Iterator i1 = nodeAnnots.iterator();
608 while (i1.hasNext()) {
609 Annotation annotNode = (Annotation) i1.next();
610 if (processed.containsKey(annotNode.getId()))
611 continue;
612 processChildrenAnnots(annotNode, processed);
613 }
615 selection.clear();
616
617 this.scrollRectToVisible(new
618 Rectangle(0, (int) getHeight()- (int) getVisibleRect().getHeight(),
619 (int) getVisibleRect().getWidth(), (int) getVisibleRect().getHeight()));
620 }
622 private JButton processChildrenAnnots(Annotation annot, HashMap processed) {
623 selection.clear();
624 Vector childrenButtons = new Vector();
625 java.util.List children =
626 (java.util.List) annot.getFeatures().get(NODE_CONSISTS_FEATURE_NAME);
627
628 for (Iterator i = children.iterator(); i.hasNext(); ) {
629 Integer childId = (Integer) i.next();
630 Annotation child = treeAnnotations.get(childId);
631 JButton childButton;
632
633 if (processed.containsKey(child.getId()))
634 childButton = (JButton) processed.get(child.getId());
635 else
636 childButton = processChildrenAnnots(child, processed);
637
638 childrenButtons.add(childButton);
639 }
640
641 selection = (Vector) childrenButtons.clone();
642 STreeNode parent = createParentNode(
643 (String) annot.getFeatures().get(NODE_CAT_FEATURE_NAME),
644 annot);
645 nonTerminals.put(new Integer(parent.getID()), parent);
646 JButton parentButton = createCentralButton(parent);
647 addLines(parent);
648
649 processed.put(annot.getId(), parentButton);
650 selection.clear();
651 return parentButton;
652 }
654 private STreeNode findLeaf(Node start, Node end) {
655 for (Iterator i = leaves.values().iterator(); i.hasNext(); ) {
656 STreeNode node = (STreeNode) i.next();
657 if (node.getStart() == start.getOffset().intValue() &&
658 node.getEnd() == end.getOffset().intValue()
659 )
660 return node;
661 }
662
663 return null;
664 }
666
667
670 private void utterances2Trees() {
671
672 if (! utterance.getType().equals(textAnnotationType)) {
673 Out.println("Can't display annotations other than the specified type:" +
674 textAnnotationType);
675 return;
676 }
677
678 utteranceStartOffset = utterance.getStartNode().getOffset();
681 utteranceEndOffset = utterance.getEndNode().getOffset();
682
683 try {
684 displayedString = currentSet.getDocument().getContent().getContent(
685 utteranceStartOffset, utteranceEndOffset).toString();
686 } catch (InvalidOffsetException ioe) {
687 ioe.printStackTrace(Err.getPrintWriter());
688 }
689
690 AnnotationSet tokensAS = currentSet.get(tokenType, utteranceStartOffset,
691 utteranceEndOffset);
692 if (tokensAS == null || tokensAS.isEmpty()) {
693 Out.println("TreeViewer warning: No annotations of type " + tokenType +
694 "so cannot show or edit the text and the tree annotations.");
695 return;
696 }
697
698 Insets insets = this.getInsets();
699 int buttonX = insets.left;
701
702 int buttonY = this.getHeight() - 20 - insets.bottom;
704
705 java.util.List tokens = new ArrayList(tokensAS);
706 if (tokens.isEmpty())
708 return;
709 Collections.sort(tokens, new gate.util.OffsetComparator());
710
711 for (int i= 0; i< tokens.size(); i++) {
713 Annotation tokenAnnot = (Annotation) tokens.get(i);
714 Long tokenBegin = tokenAnnot.getStartNode().getOffset();
715 Long tokenEnd = tokenAnnot.getEndNode().getOffset();
716
717 String tokenText = "";
718 try {
719 tokenText = document.getContent().getContent(
720 tokenBegin, tokenEnd).toString();
721 } catch (InvalidOffsetException ioe) {
722 ioe.printStackTrace(Err.getPrintWriter());
723 }
724
725 STreeNode node =
727 new STreeNode(tokenBegin.longValue(), tokenEnd.longValue());
728
729 node.setAllowsChildren(false);
731
732 node.setUserObject(tokenText);
734 node.setLevel(0);
735
736 leaves.put(new Integer(node.getID()), node);
738
739 buttonX = createButton4Node(node, buttonX, buttonY);
741
742 }
744
745
786
787 this.setSize(buttonX, buttonY + 20 + insets.bottom);
788 this.setPreferredSize(this.getSize());
790
791 }
793
798 private int createButton4Node(STreeNode node, int buttonX, int buttonY) {
799
800 JButton button = new JButton((String) node.getUserObject());
801 button.setBorderPainted(false);
802
803 FontMetrics fm = button.getFontMetrics(button.getFont());
804
805 int buttonWidth,
806 buttonHeight;
807
808
811 buttonWidth = fm.stringWidth(button.getText())
812 + button.getMargin().left + button.getMargin().right
813 + extraButtonWidth;
814 buttonHeight = fm.getHeight() + button.getMargin().top +
815 button.getMargin().bottom;
816 buttonY = buttonY - buttonHeight;
817
818
821 button.setBounds(buttonX, buttonY, buttonWidth, buttonHeight);
822 button.addActionListener(this);
823 button.addMouseListener(this);
824 button.setActionCommand("" + node.getID());
825 button.setVisible(true);
826 button.setEnabled(true);
827
828 this.add(button);
829 buttons.put(new Integer(node.getID()), button);
830
831 buttonX += buttonWidth + horizButtonGap;
832 return buttonX;
833
834 }
836 private JButton createCentralButton(STreeNode newNode) {
837
838 FocusButton button = new FocusButton((String) newNode.getUserObject());
839 button.setBorderPainted(false);
840
841 FontMetrics fm = button.getFontMetrics(button.getFont());
842
843 int buttonWidth,
844 buttonHeight,
845 buttonX = 0,
846 buttonY =0;
847
848
851 buttonWidth = fm.stringWidth(button.getText())
852 + button.getMargin().left + button.getMargin().right
853 + extraButtonWidth;
854 buttonHeight = fm.getHeight() + button.getMargin().top +
855 button.getMargin().bottom;
856
857 int left = this.getWidth(), right =0 , top = this.getHeight();
858
859 for (Iterator i = selection.iterator(); i.hasNext(); ) {
861 JButton childButton = (JButton) i.next();
862
863 if (left > childButton.getX())
864 left = childButton.getX();
865 if (childButton.getX() + childButton.getWidth() > right)
866 right = childButton.getX() + childButton.getWidth();
867 if (childButton.getY() < top)
868 top = childButton.getY();
869 }
870
871 buttonX = (left + right) /2 - buttonWidth/2;
872 buttonY = top - vertButtonGap;
873
875 button.setBounds(buttonX, buttonY, buttonWidth, buttonHeight);
878 button.addActionListener(this);
879 button.addMouseListener(this);
880
885 button.setActionCommand("" + newNode.getID());
886
887 this.add(button);
888 buttons.put(new Integer(newNode.getID()), button);
890
891 if (buttonY < 0) {
893 this.setSize(this.getWidth(), this.getHeight() + 5* (- buttonY));
894 this.setPreferredSize(this.getSize());
895 shiftButtonsDown(5* (-buttonY));
896 }
897
898 return button;
899 }
901 private void shiftButtonsDown(int offset) {
902 for (Iterator i = buttons.values().iterator(); i.hasNext(); ) {
903 JButton button = (JButton) i.next();
904 button.setBounds( button.getX(),
905 button.getY() + offset,
906 button.getWidth(),
907 button.getHeight());
908 }
910 for (Iterator k = lines.iterator(); k.hasNext(); ) {
911 Coordinates coords = (Coordinates) k.next();
912 coords.setY1(coords.getY1() + offset);
913 coords.setY2(coords.getY2() + offset);
914 }
915 }
917 public void actionPerformed(ActionEvent e) {
918
919 if (e.getSource() instanceof JMenuItem) {
921 JMenuItem menuItem = (JMenuItem) e.getSource();
922
923 if (popup.getLabel().equals("leaves")) {
927 Integer id = new Integer(e.getActionCommand());
928
929 JButton button = (JButton) buttons.get(id);
931 selection.add(button);
932
933 STreeNode leaf = (STreeNode) leaves.get(id);
934
935 STreeNode parent = new STreeNode(leaf.getStart(), leaf.getEnd());
939 parent.setLevel(leaf.getLevel()+1); parent.add(leaf);
941
942 parent.setUserObject(menuItem.getText());
944
945 parent.createAnnotation( document,
947 treeNodeAnnotationType,
948 displayedString,
949 utteranceStartOffset.longValue());
950 nonTerminals.put(new Integer(parent.getID()), parent);
951
952 createCentralButton(parent);
954
955 addLines(parent);
957
958 clearSelection();
959
960 this.repaint();
962 } else if (popup.getLabel().equals("non-terminal")) {
964 Integer id = new Integer(e.getActionCommand());
967
968 JButton button = (JButton) buttons.get(id);
970 selection.add(button);
971
972 STreeNode parent = createParentNode(menuItem.getText());
974
975 nonTerminals.put(new Integer(parent.getID()), parent);
977
978 createCentralButton(parent);
980
981 addLines(parent);
983
984 clearSelection();
985
986 this.repaint();
988
989 }
991 }
993
994 }
996 public void mouseClicked(MouseEvent e) {
997
998 if (! (e.getSource() instanceof JButton))
999 return;
1000
1001 JButton source = (JButton) e.getSource();
1002
1003 if ((! (e.isControlDown() || e.isShiftDown()))
1005 && SwingUtilities.isLeftMouseButton(e))
1006 clearSelection();
1007
1008 if (SwingUtilities.isLeftMouseButton(e))
1010 selectNode(e);
1012
1013
1014 if (SwingUtilities.isRightMouseButton(e)) {
1016 if ( source.getBackground() != selectedNodeColor ) {
1018 source.grabFocus();
1019 source.doClick();
1020 selectNode(e);
1021 }
1022 showRightClickPopup(e);
1024 }
1026 }
1028 public void mousePressed(MouseEvent e) {
1029 }
1030
1031 public void mouseReleased(MouseEvent e) {
1032 }
1033
1034 public void mouseEntered(MouseEvent e) {
1035 }
1036
1037 public void mouseExited(MouseEvent e) {
1038 }
1040
1041 private void showRightClickPopup(MouseEvent e) {
1042
1043 JButton source = (JButton) e.getSource();
1045 Integer id = new Integer(source.getActionCommand());
1046
1047 Object obj = leaves.get(id);
1049 if (obj != null) {
1050 STreeNode leaf = (STreeNode) obj;
1051 if (leaf.getParent() != null) {
1053 clearSelection();
1054 JOptionPane.showMessageDialog(
1055 this,
1056 "Node already annotated. To delete the existing annotation, " +
1057 "select it and press <DEL>.",
1058 "Syntax Tree Viewer message",
1059 JOptionPane.INFORMATION_MESSAGE);
1060 return;
1061 }
1062
1063 popup.setLabel("leaves");
1065 setMenuCommands(popup, ""+id);
1066
1067 popup.pack();
1068 popup.show(source, e.getX(), e.getY());
1069 } else {
1071 if ( ((STreeNode) nonTerminals.get(id)).getParent() != null) {
1073 clearSelection();
1074 JOptionPane.showMessageDialog(this, "Node already annotated. To delete"+
1075 " the existing annotation, select it and press <DEL>.",
1076 "Syntax Tree Viewer message",
1077 JOptionPane.INFORMATION_MESSAGE);
1078 return; }
1080
1081 popup.setLabel("non-terminal");
1082 setMenuCommands(popup, ""+id);
1083
1084 popup.pack();
1085 popup.show(source, e.getX(), e.getY());
1086
1087 }
1088
1089 }
1091 private void addLines(STreeNode newNode) {
1092
1093 JButton newButton = (JButton) buttons.get(new Integer(newNode.getID()));
1094 int nbX = newButton.getX() + newButton.getWidth()/2;
1095 int nbY = newButton.getY() + newButton.getHeight();
1096
1097 for (Iterator i = selection.iterator(); i.hasNext(); ) {
1098 JButton selButton = (JButton) i.next();
1099
1100 Coordinates coords = new Coordinates(
1103 nbX,
1104 nbY,
1105 selButton.getX() + selButton.getWidth()/2,
1106 selButton.getY());
1107
1108 lines.add(coords);
1109 }
1110
1111 }
1113 private void clearSelection() {
1114 for (Enumeration enumeration = selection.elements(); enumeration.hasMoreElements(); ) {
1115 JButton selButton = (JButton) enumeration.nextElement();
1116 selButton.setBackground(buttonBackground);
1117 }
1118
1119 selection.clear();
1120
1121 }
1123
1124 private void fillCategoriesMenu() {
1125 boolean found = false;
1126
1127 CreoleRegister creoleReg = Gate.getCreoleRegister();
1129 java.util.List currentAnnotationSchemaList =
1130 creoleReg.getLrInstances("gate.creole.AnnotationSchema");
1131 if (currentAnnotationSchemaList.isEmpty()) return;
1132
1133 Iterator iter = currentAnnotationSchemaList.iterator();
1134 while (iter.hasNext()){
1135 AnnotationSchema annotSchema = (AnnotationSchema) iter.next();
1136 if (treeNodeAnnotationType.equals(annotSchema.getAnnotationName())) {
1138 found = true;
1139 FeatureSchema categories = annotSchema.getFeatureSchema(NODE_CAT_FEATURE_NAME);
1140 for (Iterator i =
1142 categories.getPermissibleValues().iterator(); i.hasNext(); ) {
1143
1144 JMenuItem menuItem = new JMenuItem( (String) i.next() );
1145 menuItem.addActionListener(this);
1146 popup.add(menuItem);
1147 }
1149 } }
1152 if (! found)
1154 Out.println("Warning: You need to define an annotation schema for " +
1155 treeNodeAnnotationType +
1156 " in order to be able to add such annotations.");
1157
1158 }
1160
1163 private void setMenuCommands(JPopupMenu menu, String command) {
1164 for (int i = 0; i < menu.getComponentCount() ; i++) {
1165 JMenuItem item = (JMenuItem) menu.getComponent(i);
1166 item.setActionCommand(command);
1167 }
1168
1169 }
1171
1174 protected STreeNode createParentNode(String text) {
1175 STreeNode parentNode = new STreeNode();
1176
1177 long begin = 2147483647, end = 0, level= -1;
1178 for (Iterator i = selection.iterator(); i.hasNext(); ) {
1179 JButton button = (JButton) i.next();
1180 Integer id = new Integer(button.getActionCommand());
1181
1182 STreeNode child = (STreeNode) nonTerminals.get(id);
1183
1184 if (begin > child.getStart())
1185 begin = child.getStart();
1186 if (end < child.getEnd())
1187 end = child.getEnd();
1188 if (level < child.getLevel())
1189 level = child.getLevel();
1190
1191 parentNode.add(child);
1192
1193 }
1195 parentNode.setLevel(level+1);
1196 parentNode.setStart(begin);
1197 parentNode.setEnd(end);
1198 parentNode.setUserObject(text);
1199 parentNode.createAnnotation(document,
1200 treeNodeAnnotationType,
1201 displayedString,
1202 utteranceStartOffset.longValue());
1203
1204
1205 return parentNode;
1206 }
1207
1208
1211 protected STreeNode createParentNode(String text, Annotation annot) {
1212 STreeNode parentNode = new STreeNode(annot);
1213
1214 long level = -1;
1215 for (Iterator i = selection.iterator(); i.hasNext(); ) {
1216 JButton button = (JButton) i.next();
1217 Integer id = new Integer(button.getActionCommand());
1218
1219 STreeNode child = (STreeNode) nonTerminals.get(id);
1220
1221 if (level < child.getLevel())
1222 level = child.getLevel();
1223
1224 parentNode.add(child);
1225 }
1227 parentNode.setLevel(level+1);
1228 parentNode.setUserObject(text);
1229
1230 return parentNode;
1231 }
1232
1233
1234 void selectNode(MouseEvent e) {
1235 if (e.getSource() instanceof JButton) {
1237 JButton source = (JButton) e.getSource();
1238
1239 selection.add(source);
1240 buttonBackground = source.getBackground();
1241 source.setBackground(selectedNodeColor);
1242 }
1243 }
1244
1245 void removeNode(JButton button) {
1247
1248 Integer id = new Integer(button.getActionCommand());
1249 STreeNode node = (STreeNode) nonTerminals.get(id);
1250 nonTerminals.remove(node);
1251 node.removeAnnotation(document);
1252
1253 resetChildren(node);
1255 removeNodesAbove(node);
1256
1257 buttons.remove(button);
1259 button.setVisible(false);
1260 this.remove(button);
1261
1262 recalculateLines();
1264
1265 selection.clear();
1267 repaint();
1268 }
1269
1270 private void resetChildren(STreeNode node) {
1272 for (Enumeration e = node.children(); e.hasMoreElements(); )
1273 ((STreeNode) e.nextElement()).setParent(null);
1274
1275 node.disconnectChildren();
1276 }
1277
1278 private void removeNodesAbove(STreeNode node) {
1279 STreeNode parent = (STreeNode) node.getParent();
1280
1281 while (parent != null) {
1282 Integer id = new Integer(parent.getID());
1283 parent.removeAnnotation(document);
1284 if (parent.isNodeChild(node))
1285 parent.remove(node);
1286 parent.disconnectChildren();
1287
1288 nonTerminals.remove(id);
1289
1290 JButton button = (JButton) buttons.get(id);
1291 this.remove(button);
1292 buttons.remove(id);
1293
1294 parent = (STreeNode) parent.getParent();
1295 }
1296 }
1297
1298 private void recalculateLines() {
1299 lines.clear();
1300 for (Iterator i = nonTerminals.values().iterator(); i.hasNext(); )
1302 recalculateLines((STreeNode) i.next());
1303
1304 }
1305
1306
1309 private void recalculateLines(STreeNode node) {
1310 Integer id = new Integer(node.getID());
1311 JButton button = (JButton) buttons.get(id);
1312
1313 int bX = button.getX() + button.getWidth()/2;
1314 int bY = button.getY() + button.getHeight();
1315
1316 for (Enumeration e = node.children(); e.hasMoreElements(); ) {
1317 STreeNode subNode = (STreeNode) e.nextElement();
1318 Integer sid = new Integer(subNode.getID());
1319 JButton subButton = (JButton) buttons.get(sid);
1320
1321 Coordinates coords = new Coordinates(
1322 bX,
1323 bY,
1324 subButton.getX() + subButton.getWidth()/2,
1325 subButton.getY());
1326
1327 lines.add(coords);
1328 }
1329
1330 }
1331
1332
1342
1343 public void setTreeNodeAnnotationType(String newTreeNodeAnnotationType) {
1344 treeNodeAnnotationType = newTreeNodeAnnotationType;
1345 }
1346
1347 public String getTreeNodeAnnotationType() {
1348 return treeNodeAnnotationType;
1349 }
1350
1351 public void setTokenType(String newTokenType) {
1352 if (newTokenType != null && ! newTokenType.equals(""))
1353 tokenType = newTokenType;
1354 }
1355
1356 public String getTokenType() {
1357 return tokenType;
1358 }
1359
1360 void this_componentShown(ComponentEvent e) {
1361 Out.println("Tree Viewer shown");
1362 }
1363
1364 void this_componentHidden(ComponentEvent e) {
1365 Out.println("Tree Viewer closes");
1366 }
1367
1368
1382
1383 private static class FocusButton extends JButton {
1384
1385 public FocusButton(String text) {
1386 super(text);
1387 }
1388
1389 public FocusButton() {
1390 super();
1391 }
1392
1393 public FocusButton(Icon icon) {
1394 super(icon);
1395 }
1396
1397 public FocusButton(String text, Icon icon) {
1398 super(text, icon);
1399 }
1401
1405 public void processComponentKeyEvent(KeyEvent e) {
1406 super.processComponentKeyEvent(e);
1407
1408 if (e.getID() != KeyEvent.KEY_RELEASED)
1412 return;
1413
1414 if (e.getKeyCode() == KeyEvent.VK_DELETE) {
1415 SyntaxTreeViewer viewer = (SyntaxTreeViewer) ((JButton) e.getSource()).getParent();
1416 viewer.removeNode((JButton) e.getSource());
1417 }
1418 }
1420 }
1421}
1423
1424
1425