1   package debugger.gui.debugging;
2   
3   import debugger.gui.*;
4   import debugger.gui.debugging.debugviews.*;
5   import debugger.resources.*;
6   import debugger.resources.pr.*;
7   
8   import javax.swing.*;
9   import javax.swing.text.*;
10  
11  import java.awt.*;
12  import java.awt.event.*;
13  import java.util.*;
14  
15  import gate.*;
16  import gate.util.*;
17  import gate.Document;
18  
19  /**
20   * This class creates GUI of debugging (now TraceHistory) part of JAPEDebugger.
21   * @author Andrey Shafirin, Oleg Mishchenko
22   */
23  public class JapeDebuggingPanel extends JPanel {
24      private JPanel rulePanel;
25      private JLabel phaseName;
26      private JLabel ruleName;
27      private JTextPane selectedTextPane;
28      private JTextPane rulePane;
29      private JButton nextAnnotationButton;
30      private JButton previousAnnotationButton;
31  
32      private PhaseModel currentPhaseModel;
33      private RuleModel currentRuleModel;
34      private TraceContainer traceContainer;
35      private Document document;
36      private int currentStartOffset;
37      private int currentEndOffset;
38      private TraceContainer currentTraces;
39      private RuleTrace currentRuleTrace;
40      private AnnotationSet currentAnnotationCut;
41  
42      public JapeDebuggingPanel() {
43          initGui();
44      }
45  
46      private void initGui() {
47          this.setLayout(new GridBagLayout());
48          GridBagConstraints c = new GridBagConstraints();
49  
50          c.gridx = 0;
51          c.gridy = 0;
52          c.weightx = 0;
53          c.weighty = 0;
54          c.gridwidth = 1;
55          c.fill = GridBagConstraints.HORIZONTAL;
56          this.add(getUpperPanel(), c);
57  
58          c.gridx = 0;
59          c.gridy = 1;
60          c.weightx = 1;
61          c.weighty = 1;
62          c.gridwidth = 1;
63          c.fill = GridBagConstraints.BOTH;
64  
65          JScrollPane ruleScrollPane = new JScrollPane(getRulePane(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
66          ruleScrollPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Rule Text"));
67  
68          JScrollPane panelScrollPane = new JScrollPane(getRulePanel(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
69          panelScrollPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Rule"));
70  
71          JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panelScrollPane, ruleScrollPane);
72          splitPane.setDividerLocation(200);
73  //        JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, splitPane, getSelectedTextPane());
74  //        sp.setDividerLocation(300);
75  //        this.add(sp, c);
76          this.add(splitPane, c);
77          c.gridy = 2;
78          c.weighty = 0;
79          c.fill = GridBagConstraints.NONE;
80  //        this.add(getSelectedTextPane(), c);
81      }
82  
83      private JTextPane getRulePane() {
84          if (rulePane == null) {
85              rulePane = new JTextPane();
86              rulePane.setEditorKit(new StyledEditorKit());
87              rulePane.setDocument(new SyntaxDocument());
88              rulePane.setEditable(false);
89              // prevents autoscrolling of the caret
90              rulePane.setCaret(new DefaultCaret() {
91                  protected void adjustVisibility(Rectangle nloc) {
92                  }
93              });
94          }
95          return rulePane;
96      }
97  
98      private JComponent getSelectedTextPane() {
99          selectedTextPane = new JTextPane();
100         selectedTextPane.setEditable(false);
101         // prevents autoscrolling of the caret
102         selectedTextPane.setCaret(new DefaultCaret() {
103             protected void adjustVisibility(Rectangle nloc) {
104             }
105         });
106         nextAnnotationButton = new JButton("Next");
107         previousAnnotationButton = new JButton("Previous");
108         JPanel panel = new JPanel(new GridBagLayout());
109         GridBagConstraints c = new GridBagConstraints();
110         c.fill = GridBagConstraints.BOTH;
111         c.gridx = 0;
112         c.gridy = 0;
113         c.weightx = 1;
114         c.weighty = 1;
115 //        panel.add(selectedTextPane, c);
116         c.fill = GridBagConstraints.NONE;
117         c.gridx = 0;//1;
118         c.weightx = 0;
119         c.weighty = 0;
120         panel.add(previousAnnotationButton, c);
121         previousAnnotationButton.setEnabled(false);
122         previousAnnotationButton.addActionListener(new ActionListener() {
123             public void actionPerformed(ActionEvent e) {
124                 if (currentTraces != null && currentRuleModel != null && currentRuleTrace != null) {
125                     int index = currentTraces.lastIndexOf(currentRuleTrace);
126                     if (index > 0) {
127                         updateRulePanel(currentRuleModel, (RuleTrace) currentTraces.get(index - 1));
128                         currentRuleTrace = (RuleTrace) currentTraces.get(index - 1);
129                     }
130                     if (index - 1 == 0) {
131                         previousAnnotationButton.setEnabled(false);
132                     } else {
133                         previousAnnotationButton.setEnabled(true);
134                     }
135                     if (index < currentTraces.size() && currentTraces.size() > 1) {
136                         nextAnnotationButton.setEnabled(true);
137                     }
138                 }
139                 GuiFactory.getResourceView().repaint();
140             }
141         });
142         c.gridx = 1;//2;
143         panel.add(nextAnnotationButton, c);
144         nextAnnotationButton.setEnabled(false);
145         nextAnnotationButton.addActionListener(new ActionListener() {
146             public void actionPerformed(ActionEvent e) {
147                 if (currentTraces != null && currentRuleModel != null && currentRuleTrace != null) {
148                     int index = currentTraces.lastIndexOf(currentRuleTrace);
149                     if (index + 1 < currentTraces.size()) {
150                         updateRulePanel(currentRuleModel, (RuleTrace) currentTraces.get(index + 1));
151                         currentRuleTrace = (RuleTrace) currentTraces.get(index + 1);
152                     }
153                     if (index + 2 >= currentTraces.size()) {
154                         nextAnnotationButton.setEnabled(false);
155                     } else {
156                         nextAnnotationButton.setEnabled(true);
157                     }
158                     if (index + 1 > 0) {
159                         previousAnnotationButton.setEnabled(true);
160                     }
161                     GuiFactory.getResourceView().repaint();
162                 }
163             }
164         });
165         return panel;
166     }
167 
168     private JComponent getRulePanel() {
169         if (rulePanel == null) {
170             rulePanel = new JPanel();
171         }
172         return rulePanel;
173     }
174 
175     private JComponent getUpperPanel() {
176         JPanel panel = new JPanel(new GridBagLayout());
177         GridBagConstraints c = new GridBagConstraints();
178         c.gridx = 0;
179         c.gridy = 0;
180         c.weightx = 0;
181         c.weighty = 0;
182         c.anchor = GridBagConstraints.WEST;
183         c.insets = new Insets(0, 4, 0, 0);
184         panel.add(new JLabel("Rule: "), c);
185 
186         c.gridx = 1;
187         ruleName = new JLabel();
188         panel.add(ruleName, c);
189 
190         c.gridx = 2;
191         c.weightx = 1;
192         panel.add(new JPanel(), c);
193         c.gridx = 3;
194         c.weightx = 0;
195         panel.add(new JPanel(), c);
196         c.gridx = 3;
197         c.gridwidth = 2;
198         panel.add(new JPanel(), c);
199 
200         c.gridx = 0;
201         c.gridy = 1;
202         c.weightx = 1;
203         c.gridwidth = 3;
204         panel.add(new JPanel(), c);
205 
206         c.gridwidth = 1;
207         c.gridx = 3;
208         c.weightx = 0;
209         c.anchor = GridBagConstraints.EAST;
210         panel.add(new JLabel("Phase: "), c);
211 
212         c.gridx = 4;
213         phaseName = new JLabel();
214         panel.add(phaseName, c);
215 
216         c.gridx = 0;
217         c.gridy = 2;
218         c.weightx = 0;
219         c.weighty = 0;
220         c.gridwidth = 2;
221         c.fill = GridBagConstraints.NONE;
222         c.anchor = GridBagConstraints.WEST;
223         c.insets = new Insets(0, 0, 4, 0);
224         panel.add(getSelectedTextPane(), c);
225 
226         return panel;
227     }
228 
229     /**
230      * This method is called from <code>ShowResultAction</code> action, when user selects
231      * text, on which he'd like to see the results of matching the rules.
232      * @param startOffset
233      * @param endOffset
234      * @param document
235      */
236     public void setText(int startOffset, int endOffset, Document document) {
237         TraceContainer traceContainer = ResourcesFactory.getPhaseController().getRuleTrace();
238         traceContainer = traceContainer.getTraceByOffset(new Long(startOffset), new Long(endOffset));
239         try {
240             this.selectedTextPane.setText(document.getContent().getContent(new Long(startOffset), new Long(endOffset)).toString());
241         } catch (InvalidOffsetException e) {
242             e.printStackTrace();
243         }
244         this.traceContainer = traceContainer;
245         this.document = document;
246         this.currentStartOffset = startOffset;
247         this.currentEndOffset = endOffset;
248         //////
249         this.updateRulePanel(null, null);
250         //////
251         this.repaint();
252     }
253 
254     /**
255      * This method creates a panel with annotations of the given input type, which are
256      * contained in a selected interval. All of the annotations which matched in the
257      * current selected rule are highlighted. (Input type is one of the inputs in the phase, to
258      * which current rule belongs.)
259      * @param annotations <code>AnnotationSet</code> with annotations of the given input type
260      *        from a selected interval (offsets are <code>currentStartOffset</code> and
261      *        <code>currentEndOffset</code>)
262      * @param annotationsType type of annotations, i.e. Lookup, Morph
263      * @param ruleTrace <code>RuleTrace</code> of currently selected rule, can be null,
264      *        if no rule is selected
265      * @param withHighlighting whether highlighting is on/off
266      * @return
267      */
268     private JComponent createAnnotationPanel(AnnotationSet annotations, String annotationsType, RuleTrace ruleTrace, boolean withHighlighting) {
269         JPanel panel = new JPanel(new GridBagLayout());
270         GridBagConstraints c = new GridBagConstraints();
271 
272         c.gridx = 0;
273         c.gridy = 0;
274         c.weightx = 0;
275         c.weighty = 0;
276         c.gridwidth = 1;
277         c.gridheight = 1;
278         c.anchor = GridBagConstraints.WEST;
279         c.fill = GridBagConstraints.NONE;
280 
281         // Matched annotations
282         AnnotationSet annotationsToHighlight = null;
283         if (ruleTrace != null) {
284             annotationsToHighlight = ruleTrace.getAnnotations();
285         }
286 
287         long lastNodeOffset = 0;
288         if (annotationsToHighlight != null) {
289             lastNodeOffset = annotationsToHighlight.lastNode().getOffset().longValue();
290         }
291 
292         // Annotations to display
293         HashSet annotationsToShowSet = new HashSet();
294         if (annotations != null) {
295             annotationsToShowSet.addAll(annotations);
296         }
297 
298         // Add some Token annotations to displayed annotations
299         HashSet tokensNotToBeIncluded = new HashSet();
300         for (Iterator it = annotationsToShowSet.iterator(); it.hasNext();) {
301             Annotation currentAnnotation = (Annotation) it.next();
302             AnnotationSet containedTokens = currentAnnotationCut.getContained(currentAnnotation.getStartNode().getOffset(), currentAnnotation.getEndNode().getOffset()).get("Token");
303             if (containedTokens != null) {
304                 tokensNotToBeIncluded.addAll(containedTokens);
305             }
306         }
307         AnnotationSet tokenAnnotationSet = currentAnnotationCut.get("Token", new Long(currentStartOffset), new Long(currentEndOffset));
308         if (tokenAnnotationSet != null) {
309             for (Iterator it = tokenAnnotationSet.iterator(); it.hasNext();) {
310                 Annotation currentAnnotation = (Annotation) it.next();
311                 if (!tokensNotToBeIncluded.contains(currentAnnotation)) {
312                     annotationsToShowSet.add(currentAnnotation);
313                 }
314             }
315         }
316         // end of adding tokens
317 
318         // Now let's sort all the annotations we'd like to display
319         ArrayList list = new ArrayList(annotationsToShowSet);
320         Collections.sort(list, new OffsetComparator());
321         /*
322          * Offset comparator doesn't always work as
323          * we need - the longest annotation with
324          * the same start offset should ALWAYS be first.
325          * So I have to use my own comparator.
326          */
327         Collections.sort(list, new Comparator() {
328             public int compare(Object o1, Object o2) {
329                 Annotation a1 = (Annotation) o1;
330                 Annotation a2 = (Annotation) o2;
331                 long offset1 = a1.getStartNode().getOffset().longValue();
332                 long offset2 = a2.getStartNode().getOffset().longValue();
333                 long length1 = a1.getEndNode().getOffset().longValue() - offset1;
334                 long length2 = a2.getEndNode().getOffset().longValue() - offset2;
335                 if (offset1 > offset2) {
336                     return 1;
337                 }
338                 if (offset1 < offset2) {
339                     return -1;
340                 }
341                 if (offset1 == offset2) {
342                     if (length1 > length2)
343                         return -1;
344                     else if (length1 < length2)
345                         return 1;
346                     else
347                         return 0;
348                 }
349                 return 0;
350             }
351         });
352         // end of sorting
353 
354         // Annotations of the same type, which should not be displayed -
355         // for example, if we have several lookups - only one lookup should be displayed
356         ArrayList annotationsToIgnore = new ArrayList();
357         boolean isRedSet = false;
358 
359         int x = 0;
360         for (Iterator it = list.iterator(); it.hasNext();) {
361             Annotation currentAnnotation = (Annotation) it.next();
362 
363             // Get annotations of the same type with the same offsets and leave only one to display
364             AnnotationSet containedAnnotationsOfTheSameType = currentAnnotationCut.getContained(currentAnnotation.getStartNode().getOffset(), currentAnnotation.getEndNode().getOffset()).get(annotationsType);
365             if (containedAnnotationsOfTheSameType != null) {
366                 for (Iterator iter = containedAnnotationsOfTheSameType.iterator(); iter.hasNext();) {
367                     Annotation ann = (Annotation) iter.next();
368                     if (!ann.equals(currentAnnotation)) {
369                         annotationsToIgnore.add(ann);
370                     }
371                 }
372             }
373 
374             // I get text to display from the Token annotations
375             AnnotationSet containedTokens = currentAnnotationCut.getContained(currentAnnotation.getStartNode().getOffset(), currentAnnotation.getEndNode().getOffset()).get("Token");
376             ArrayList containedTokensList = null;
377             if (containedTokens != null) {
378                 containedTokensList = new ArrayList(containedTokens);
379             } else {
380                 containedTokensList = new ArrayList();
381             }
382             Collections.sort(containedTokensList, new OffsetComparator());
383 
384             // This variable shows the number of the created panel in a row
385             int order = 0;
386             if (!annotationsToIgnore.contains(currentAnnotation)) {
387                 // At last we create the panels with (or without) text on them
388                 for (Iterator iter = containedTokensList.iterator(); iter.hasNext();) {
389                     Annotation currentTokenAnnotation = (Annotation) iter.next();
390                     String text = (String) currentTokenAnnotation.getFeatures().get("string");
391                     PrimaryTextPanel textPanel = new PrimaryTextPanel(text, false, PrimaryTextPanel.OPEN_NONE);
392                     if (containedAnnotationsOfTheSameType != null) {
393                         textPanel.setAnnotations(new ArrayList(containedAnnotationsOfTheSameType));
394                     } else {
395                         ArrayList arr = new ArrayList();
396                         arr.add(currentAnnotation);
397                         textPanel.setAnnotations(arr);
398                     }
399                     if (containedTokens.size() == 1) {
400                         textPanel.setOpenMode(PrimaryTextPanel.OPEN_NONE);
401                     } else if (order == 0 && containedTokens.size() > 1) {
402                         textPanel.setOpenMode(PrimaryTextPanel.OPEN_RIGHT);
403                     } else if (order == (containedTokens.size() - 1)) {
404                         textPanel.setOpenMode(PrimaryTextPanel.OPEN_LEFT);
405                     } else {
406                         textPanel.setOpenMode(PrimaryTextPanel.OPEN_BOTH);
407                     }
408 
409                     // highlighting
410                     if (currentTokenAnnotation.equals(currentAnnotation) && !annotationsType.equals("Token")) {
411                         textPanel.setTextVisible(false);
412                     }
413                     if (annotationsToHighlight != null && annotationsToHighlight.contains(currentAnnotation) && textPanel.isTextVisible() && withHighlighting) {
414                         textPanel.setHighlighted(true);
415                     }
416                     if (containedAnnotationsOfTheSameType != null) {
417                         for (Iterator iterator = containedAnnotationsOfTheSameType.iterator(); iterator.hasNext();) {
418                             Annotation a = (Annotation) iterator.next();
419                             if (annotationsToHighlight != null && annotationsToHighlight.contains(a) && textPanel.isTextVisible()) {
420                                 int startOffset = a.getStartNode().getOffset().intValue();
421                                 int endOffset = a.getEndNode().getOffset().intValue();
422                                 int tokenStartOffset = currentTokenAnnotation.getStartNode().getOffset().intValue();
423                                 int tokenEndOffset = currentTokenAnnotation.getEndNode().getOffset().intValue();
424                                 if (startOffset <= tokenStartOffset && tokenEndOffset <= endOffset && endOffset >= tokenStartOffset && withHighlighting) {
425                                     textPanel.setHighlighted(true);
426                                 }
427                             }
428                         }
429                     }
430                     if (ruleTrace != null && !ruleTrace.isFinished() && currentAnnotation.getStartNode().getOffset().longValue() >= lastNodeOffset
431                             && !isRedSet && textPanel.isTextVisible() && withHighlighting) {
432                         textPanel.setRed(true);
433                         if (textPanel.getOpenMode() == PrimaryTextPanel.OPEN_NONE || textPanel.getOpenMode() == PrimaryTextPanel.OPEN_LEFT) {
434                             isRedSet = true;
435                         }
436                     }
437                     // end of highlighting
438 
439                     // Set standard annotation tooltip - annotation's features
440                     String toolTipText = "";
441                     FeatureMap featureMap = null;
442                     if (ruleTrace != null) {
443                         featureMap = ruleTrace.getPattern(currentAnnotation);
444                     }
445                     if (featureMap == null && containedAnnotationsOfTheSameType != null) {
446                         if (ruleTrace != null) {
447                             for (Iterator iterator = containedAnnotationsOfTheSameType.iterator(); iterator.hasNext();) {
448                                 featureMap = ruleTrace.getPattern((Annotation) iterator.next());
449                                 if (featureMap != null)
450                                     break;
451                             }
452                         }
453                     }
454                     if (featureMap != null) {
455                         for (Iterator i = featureMap.keySet().iterator(); i.hasNext();) {
456                             toolTipText = toolTipText + " " + annotationsType + ".";
457                             Object key = i.next();
458                             toolTipText = toolTipText + key + "=" + featureMap.get(key);
459                         }
460                         if (featureMap.keySet().isEmpty()) {
461                             toolTipText = annotationsType;
462                         }
463                     }
464                     if (featureMap != null && textPanel.isTextVisible() && (textPanel.isHighlighted() || textPanel.isRed())
465                             && withHighlighting) {
466                         textPanel.setToolTipText(toolTipText);
467                     }
468                     // end of setting tooltip
469 
470                     c.gridx = x;
471                     panel.add(textPanel, c);
472                     order++;
473                     x++;
474                 }
475             }
476         }
477         return panel;
478     }
479 
480     /**
481      * Creates panels with input annotations.
482      * @param ruleModel
483      * @param currentTrace
484      */
485     public void updateRulePanel(RuleModel ruleModel, RuleTrace currentTrace) {
486         if (ruleModel != null) {
487             rulePane.setText(ruleModel.getRuleText());
488         }
489         RuleTrace ruleTrace = null;
490         if (currentTrace == null && traceContainer != null) {
491             if (traceContainer != null) {
492                 TraceContainer traces = traceContainer.getTraceByRuleModel(ruleModel);
493                 if (traces.size() > 0) {
494                     ruleTrace = (RuleTrace) traces.iterator().next();
495                 }
496                 previousAnnotationButton.setEnabled(false);
497                 nextAnnotationButton.setEnabled(false);
498                 if (traces.size() > 1) {
499                     nextAnnotationButton.setEnabled(true);
500                 }
501                 currentTraces = traces;
502                 currentRuleTrace = ruleTrace;
503             }
504         } else {
505             ruleTrace = currentTrace;
506             currentRuleTrace = ruleTrace;
507         }
508         if (traceContainer != null) {
509             currentAnnotationCut = traceContainer.getPhaseCut(currentPhaseModel);
510             JPanel panel = new JPanel();
511             panel.setLayout(new GridBagLayout());
512             GridBagConstraints c = new GridBagConstraints();
513             int i = 0;
514             c.anchor = GridBagConstraints.WEST;
515             c.insets = new Insets(2, 4, 2, 4);
516             // Create input panels
517             if (currentPhaseModel != null) {
518                 for (Iterator it = currentPhaseModel.getInput().iterator(); it.hasNext();) {
519                     String input = (String) it.next();
520                     c.fill = GridBagConstraints.NONE;
521                     c.gridx = 0;
522                     c.weightx = 0;
523                     c.gridy = i++;
524                     panel.add(new JLabel(input), c);
525                     c.gridx = 1;
526                     if (currentAnnotationCut != null) {
527                         panel.add(createAnnotationPanel(currentAnnotationCut.get(input, new Long(currentStartOffset), new Long(currentEndOffset)), input, ruleTrace, true), c);
528                     } else {
529                         panel.add(new JLabel("No annotations of type " + input + " available"), c);
530                     }
531                     c.gridx = 2;
532                     c.weightx = 1;
533                     c.fill = GridBagConstraints.HORIZONTAL;
534                     panel.add(new JPanel(), c);
535                 }
536             }
537             //end of creating input panels
538 
539             // Add divider
540             c.gridx = 0;
541             c.gridy = i;
542             c.weightx = 0;
543             c.weighty = 0;
544             c.gridwidth = 2;
545             panel.add(new JPanel() {
546                 {
547                     this.setBackground(Color.black);
548                 }
549 
550                 public Dimension getPreferredSize() {
551                     return getMaximumSize();
552                 }
553 
554                 public Dimension getMaximumSize() {
555                     return new Dimension(20, 2);
556                 }
557             },
558                     c);
559             c.gridx = 1;
560             c.weightx = 1;
561             c.gridy = i++;
562             panel.add(new JPanel(), c);
563             // end of creating divider
564 
565             // Create additional token panel
566             c.fill = GridBagConstraints.NONE;
567             c.gridx = 0;
568             c.weightx = 0;
569             c.gridy = i++;
570             panel.add(new JLabel(""), c);
571             c.gridx = 1;
572             if (document.getAnnotations().getContained(new Long(currentStartOffset), new Long(currentEndOffset)).get("Token") != null) {
573                 if (currentAnnotationCut == null) {
574                     currentAnnotationCut = document.getAnnotations().getContained(new Long(currentStartOffset), new Long(currentEndOffset)).get("Token");
575                 }
576                 panel.add(createAnnotationPanel(document.getAnnotations().getContained(new Long(currentStartOffset), new Long(currentEndOffset)).get("Token"), "Token", ruleTrace, false), c);
577             } else {
578                 panel.add(new JLabel("No annotations of type Token available"), c);
579             }
580             c.gridx = 2;
581             c.weightx = 1;
582             c.fill = GridBagConstraints.HORIZONTAL;
583             panel.add(new JPanel(), c);
584             // end of creating additional token panel
585 
586             // this panel is added to keep annotation panels on the top
587             c.gridx = 0;
588             c.gridy = i++;
589             c.weightx = 0;
590             c.weighty = 1;
591             panel.add(new JPanel(), c);
592 
593             // save changes
594             getRulePanel().removeAll();
595             getRulePanel().setLayout(new BorderLayout());
596             getRulePanel().add(panel, BorderLayout.CENTER);
597             this.revalidate();
598 
599 //            int startOffset = (int)ruleTrace.getAnnotations().firstNode().getOffset().longValue() - currentStartOffset;
600 //            int length = (int)ruleTrace.getAnnotations().lastNode().getOffset().longValue() -
601 //                    (int)ruleTrace.getAnnotations().firstNode().getOffset().longValue();
602 //            MutableAttributeSet attributeSet = new SimpleAttributeSet();
603 //            StyleConstants.setBackground(attributeSet, Color.white);
604 //            if(startOffset < 0) startOffset = 0;
605 // some bugs here...
606 //            ((DefaultStyledDocument) selectedTextPane.getDocument()).setCharacterAttributes(0, selectedTextPane.getText().length(), attributeSet, false);
607 //            StyleConstants.setBackground(attributeSet, Color.lightGray);
608 //            ((DefaultStyledDocument) selectedTextPane.getDocument()).setCharacterAttributes(0, startOffset, attributeSet, true);
609 //            StyleConstants.setBackground(attributeSet, Color.cyan);
610 //            ((DefaultStyledDocument) selectedTextPane.getDocument()).setCharacterAttributes(startOffset, length, attributeSet, false);
611         }
612 //        else
613 //        {
614 //            getRulePanel().removeAll();
615 //            getRulePanel().add(new JLabel("No annotations available"));
616 //            this.revalidate();
617 //        }
618     }
619 
620     /**
621      * Updates panel after
622      * user has selected a rule in the ResourceTree.
623      * @param ruleModel <code>RuleModel</code> which user has selected in the resources tree
624      * @see RuleModel
625      * @see debugger.gui.resources.ResourceTree
626      */
627     public void setCurrentRule(RuleModel ruleModel) {
628         currentRuleModel = ruleModel;
629         currentPhaseModel = ruleModel.getParentPhase();
630         phaseName.setText(currentPhaseModel.getName() + "   Control = " + currentPhaseModel.getControl());
631         ruleName.setText(ruleModel.getName());
632     }
633 
634     /**
635      * Updates panel after
636      * user has selected a phase in the ResourceTree.
637      * @param phaseModel <code>PhaseModel</code> which user has selected in the resources tree
638      * @see PhaseModel
639      * @see debugger.gui.resources.ResourceTree
640      */
641     public void setCurrentPhase(PhaseModel phaseModel) {
642         currentPhaseModel = phaseModel;
643         phaseName.setText(currentPhaseModel.getName() + "   Control = " + currentPhaseModel.getControl());
644         if (currentRuleModel != null && !currentRuleModel.getParentPhase().equals(currentPhaseModel)) {
645             getRulePanel().removeAll();
646             getRulePanel().add(new JLabel("No rule currently selected."));
647         }
648         ruleName.setText("");
649     }
650 
651     /**
652      * This method should be deleted later - it violates the architecture.
653      * @return
654      */
655     public RuleTrace getCurrentRuleTrace() {
656         return currentRuleTrace;
657     }
658 
659     /**
660      * This method should be deleted later - it violates the architecture.
661      * @return
662      */
663     public RuleModel getCurrentRuleModel() {
664         return currentRuleModel;
665     }
666 }
667