CorefEditor.java
0001 /*
0002  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
0003  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
0004  *
0005  *  This file is part of GATE (see http://gate.ac.uk/), and is free
0006  *  software, licenced under the GNU Library General Public License,
0007  *  Version 2, June 1991 (in the distribution as file licence.html,
0008  *  and also available at http://gate.ac.uk/gate/licence.html).
0009  *
0010  *  CorefEditor.java
0011  *
0012  *  Niraj Aswani, 24-Jun-2004
0013  *
0014  *  $Id: CorefEditor.java 12340 2010-03-10 13:15:05Z markagreenwood $
0015  */
0016 
0017 package gate.gui.docview;
0018 
0019 import java.awt.*;
0020 import javax.swing.*;
0021 import javax.swing.tree.*;
0022 import javax.swing.event.*;
0023 import java.util.*;
0024 import gate.*;
0025 import gate.creole.*;
0026 import java.io.*;
0027 import java.awt.event.*;
0028 import gate.swing.*;
0029 import gate.event.*;
0030 import gate.gui.MainFrame;
0031 
0032 import javax.swing.text.Highlighter;
0033 import javax.swing.text.DefaultHighlighter;
0034 
0035 /**
0036  * Display a tree that contains the co-references type of the document,
0037  * highlight co-references in the document, allow creating
0038  * co-references from existing annotations, editing and deleting co-references.
0039  */
0040 public class CorefEditor
0041     extends AbstractDocumentView
0042     implements ActionListener, gate.event.FeatureMapListener,
0043     gate.event.DocumentListener, AnnotationSetListener {
0044 
0045   // default AnnotationSet Name
0046   private final static String DEFAULT_ANNOTSET_NAME = "Default";
0047 
0048   private JPanel mainPanel, topPanel, subPanel;
0049   private JToggleButton showAnnotations;
0050   private JComboBox annotSets, annotTypes;
0051   private DefaultComboBoxModel annotSetsModel, annotTypesModel;
0052 
0053   // Co-reference Tree
0054   private JTree corefTree;
0055 
0056   // Root node
0057   private CorefTreeNode rootNode;
0058 
0059   // top level hashMap (corefChains)
0060   // AnnotationSet(CorefTreeNode) --> (CorefTreeNode type ChainNode --> ArrayList AnnotationIds)
0061   private HashMap corefChains;
0062 
0063   // This is used to store the annotationSet name and its respective corefTreeNode
0064   // annotationSetName --> CorefTreeNode of type (AnnotationSet)
0065   private HashMap corefAnnotationSetNodesMap;
0066 
0067   // annotationSetName --> (chainNodeString --> Boolean)
0068   private HashMap selectionChainsMap;
0069 
0070   // chainString --> Boolean
0071   private HashMap currentSelections;
0072 
0073   // annotationSetName --> (chainNodeString --> Color)
0074   private HashMap colorChainsMap;
0075 
0076   // chainNodeString --> Color
0077   private HashMap currentColors;
0078 
0079   private ColorGenerator colorGenerator;
0080   private TextualDocumentView textView;
0081   private JTextArea textPane;
0082 
0083   /* ChainNode --> (HighlightedTags) */
0084   private HashMap highlightedTags;
0085 
0086   /* This arraylist stores the highlighted tags for the specific selected annotation type */
0087   private ArrayList typeSpecificHighlightedTags;
0088   private TextPaneMouseListener textPaneMouseListener;
0089 
0090   /* This stores Ids of the highlighted Chain Annotations*/
0091   private ArrayList highlightedChainAnnots = new ArrayList();
0092   /* This stores start and end offsets of the highlightedChainAnnotations */
0093   private int[] highlightedChainAnnotsOffsets;
0094 
0095   /* This stores Ids of the highlighted Annotations of particular type */
0096   private ArrayList highlightedTypeAnnots = new ArrayList();
0097   /* This stores start and end offsets of highlightedTypeAnnots */
0098   private int[] highlightedTypeAnnotsOffsets;
0099 
0100   /* Timer for the Chain Tool tip action */
0101   private ChainToolTipAction chainToolTipAction;
0102   private javax.swing.Timer chainToolTipTimer;
0103 
0104   private NewCorefAction newCorefAction;
0105   private javax.swing.Timer newCorefActionTimer;
0106 
0107   private Annotation annotToConsiderForChain = null;
0108   private JWindow popupWindow;
0109   private boolean explicitCall = false;
0110   private Highlighter highlighter;
0111 
0112   /**
0113    * This method intiates the GUI for co-reference editor
0114    */
0115   protected void initGUI() {
0116 
0117     //get a pointer to the textual view used for highlights
0118     Iterator centralViewsIter = owner.getCentralViews().iterator();
0119     while (textView == null && centralViewsIter.hasNext()) {
0120       DocumentView aView = (DocumentViewcentralViewsIter.next();
0121       if (aView instanceof TextualDocumentView)
0122         textView = (TextualDocumentViewaView;
0123     }
0124     textPane = (JTextArea) ( (JScrollPanetextView.getGUI()).getViewport().
0125                getView();
0126     highlighter = textPane.getHighlighter();
0127     chainToolTipAction = new ChainToolTipAction();
0128     chainToolTipTimer = new javax.swing.Timer(500, chainToolTipAction);
0129     chainToolTipTimer.setRepeats(false);
0130     newCorefAction = new NewCorefAction();
0131     newCorefActionTimer = new javax.swing.Timer(500, newCorefAction);
0132     newCorefActionTimer.setRepeats(false);
0133 
0134     colorGenerator = new ColorGenerator();
0135 
0136     // main Panel
0137     mainPanel = new JPanel();
0138     mainPanel.setLayout(new BorderLayout());
0139 
0140     // topPanel
0141     topPanel = new JPanel();
0142     topPanel.setLayout(new BorderLayout());
0143 
0144     // subPanel
0145     subPanel = new JPanel();
0146     subPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
0147 
0148     // showAnnotations Button
0149     showAnnotations = new JToggleButton("Show");
0150     showAnnotations.addActionListener(this);
0151 
0152     // annotSets
0153     annotSets = new JComboBox();
0154     annotSets.addActionListener(this);
0155 
0156     // get all the annotationSets
0157     Map annotSetsMap = document.getNamedAnnotationSets();
0158     annotSetsModel = new DefaultComboBoxModel();
0159     if (annotSetsMap != null) {
0160       Object [] array = annotSetsMap.keySet().toArray();
0161       for(int i=0;i<array.length;i++) {
0162         ((AnnotationSetannotSetsMap.get((Stringarray[i])).addAnnotationSetListener(this);
0163       }
0164       annotSetsModel = new DefaultComboBoxModel(array);
0165     }
0166     document.getAnnotations().addAnnotationSetListener(this);
0167     annotSetsModel.insertElementAt(DEFAULT_ANNOTSET_NAME, 0);
0168     annotSets.setModel(annotSetsModel);
0169 
0170     // annotTypes
0171     annotTypesModel = new DefaultComboBoxModel();
0172     annotTypes = new JComboBox(annotTypesModel);
0173     annotTypes.addActionListener(this);
0174     subPanel.add(new JLabel("Sets : "));
0175     subPanel.add(annotSets);
0176     JPanel tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
0177     tempPanel.add(new JLabel("Types : "));
0178     tempPanel.add(annotTypes);
0179     tempPanel.add(showAnnotations);
0180     // intialises the Data
0181     initData();
0182 
0183     // and creating the tree
0184     corefTree = new JTree(rootNode);
0185     corefTree.putClientProperty("JTree.lineStyle""None");
0186     corefTree.setRowHeight(corefTree.getRowHeight() 2);
0187     corefTree.setLargeModel(true);
0188     corefTree.setAutoscrolls(true);
0189 
0190     //corefTree.setRootVisible(false);
0191     //corefTree.setShowsRootHandles(false);
0192     corefTree.addMouseListener(new CorefTreeMouseListener());
0193     corefTree.setCellRenderer(new CorefTreeCellRenderer());
0194 
0195     mainPanel.add(topPanel, BorderLayout.NORTH);
0196     mainPanel.add(new JScrollPane(corefTree), BorderLayout.CENTER);
0197     topPanel.add(subPanel, BorderLayout.CENTER);
0198     topPanel.add(tempPanel, BorderLayout.SOUTH);
0199 
0200     // get the highlighter
0201     textPaneMouseListener = new TextPaneMouseListener();
0202     annotSets.setSelectedIndex(0);
0203 
0204     // finally show the tree
0205     //annotSetSelectionChanged();
0206 
0207     document.addDocumentListener(this);
0208     document.getFeatures().addFeatureMapListener(this);
0209   }
0210 
0211   public void reinitAllVariables() {
0212 
0213     if (highlightedChainAnnots != null)
0214       highlightedChainAnnots.clear();
0215     if (highlightedTypeAnnots != null)
0216       highlightedTypeAnnots.clear();
0217     if (typeSpecificHighlightedTags != null)
0218       typeSpecificHighlightedTags.clear();
0219     highlightedChainAnnotsOffsets = null;
0220     highlightedTypeAnnotsOffsets = null;
0221     if (highlightedTags != null && highlightedTags.values() != null) {
0222       Iterator highlightsIter = highlightedTags.values().iterator();
0223       while (highlightsIter.hasNext()) {
0224         ArrayList tags = (ArrayListhighlightsIter.next();
0225         for (int i = 0; i < tags.size(); i++) {
0226           highlighter.removeHighlight(tags.get(i));
0227         }
0228       }
0229       highlightedTags.clear();
0230     }
0231 
0232     // we need to find out all the annotSetNodes and remove all the chainNodes
0233     // under it
0234     Iterator annotSetsIter = corefAnnotationSetNodesMap.keySet().iterator();
0235     while (annotSetsIter.hasNext()) {
0236       CorefTreeNode annotSetNode = (CorefTreeNodecorefAnnotationSetNodesMap.
0237                                    get(annotSetsIter.next());
0238       annotSetNode.removeAllChildren();
0239       colorChainsMap.put(annotSetNode.toString()new HashMap());
0240       selectionChainsMap.put(annotSetNode.toString()new HashMap());
0241       corefChains.put(annotSetNode, new HashMap());
0242     }
0243   }
0244 
0245       /** This methods cleans up the memory by removing all listener registrations */
0246   public void cleanup() {
0247     document.removeDocumentListener(this);
0248     document.getFeatures().removeFeatureMapListener(this);
0249   }
0250 
0251   /** Given arrayList containing Ids of the annotations, and an annotationSet, this method
0252    * returns the annotations that has longest string among the matches
0253    */
0254   public Annotation findOutTheLongestAnnotation(ArrayList matches,
0255                                                 AnnotationSet set) {
0256     if (matches == null || matches.size() == 0) {
0257       return null;
0258     }
0259     int length = 0;
0260     int index = 0;
0261     for (int i = 0; i < matches.size(); i++) {
0262       Annotation currAnn = set.get( (Integermatches.get(i));
0263       int start = currAnn.getStartNode().getOffset().intValue();
0264       int end = currAnn.getEndNode().getOffset().intValue();
0265       if ( (end - start> length) {
0266         length = end - start;
0267         index = i;
0268       }
0269     }
0270     // so now we now have the longest String annotations at index
0271     return set.get( (Integermatches.get(index));
0272   }
0273 
0274   /**
0275    * This method is called when any annotationSet is removed outside the
0276    * co-reference editor..
0277    @param de
0278    */
0279   public void annotationSetRemoved(gate.event.DocumentEvent de) {
0280     // this method removes the annotationSet from the annotSets
0281     // and all chainNodes under it
0282 
0283     String annotSet = de.getAnnotationSetName();
0284     annotSet = (annotSet == null? DEFAULT_ANNOTSET_NAME : annotSet;
0285     // find out the currently Selected annotationSetName
0286     String annotSetName = (StringannotSets.getSelectedItem();
0287     // remove it from the main data store
0288     corefChains.remove(corefAnnotationSetNodesMap.get(annotSet));
0289     // remove it from the main data store
0290     corefAnnotationSetNodesMap.remove(annotSet);
0291     // remove it from the annotationSetModel (combobox)
0292     annotSetsModel.removeElement(annotSet);
0293     annotSets.setModel(annotSetsModel);
0294     // remove it from the colorChainMap
0295     colorChainsMap.remove(annotSet);
0296     // remove it from the selectionChainMap
0297     selectionChainsMap.remove(annotSet);
0298     if (annotSetsModel.getSize() == 0) {
0299       // no annotationSet to display
0300       // so set visible false
0301       if (popupWindow != null && popupWindow.isVisible()) {
0302         popupWindow.setVisible(false);
0303       }
0304       corefTree.setVisible(false);
0305     }
0306     else {
0307       if (annotSetName.equals(annotSet)) {
0308         if (popupWindow != null && popupWindow.isVisible()) {
0309           popupWindow.setVisible(false);
0310         }
0311         if (!corefTree.isVisible())
0312           corefTree.setVisible(true);
0313 
0314         annotSets.setSelectedIndex(0);
0315         //annotSetSelectionChanged();
0316       }
0317     }
0318   }
0319 
0320   /**
0321    * This method is called when any new annotationSet is added
0322    @param de
0323    */
0324   public void annotationSetAdded(gate.event.DocumentEvent de) {
0325 
0326     String annotSet = de.getAnnotationSetName();
0327     if(annotSet == null)
0328       document.getAnnotations().addAnnotationSetListener(this);
0329     else
0330       document.getAnnotations(annotSet).addAnnotationSetListener(this);
0331 
0332     annotSet = (annotSet == null? DEFAULT_ANNOTSET_NAME : annotSet;
0333     // find out the currently Selected annotationSetName
0334     String annotSetName = (StringannotSets.getSelectedItem();
0335 
0336     // check if newly added annotationSet is the default AnnotationSet
0337     CorefTreeNode annotSetNode = null;
0338 
0339     if (annotSet.equals(DEFAULT_ANNOTSET_NAME))
0340       annotSetNode = createAnnotSetNode(document.getAnnotations()true);
0341     else
0342       annotSetNode = createAnnotSetNode(document.getAnnotations(annotSet)false);
0343 
0344     corefAnnotationSetNodesMap.put(annotSet, annotSetNode);
0345     /*annotSetsModel.addElement(annotSet);
0346     annotSets.setModel(annotSetsModel);*/
0347 
0348     if (annotSetName != null)
0349       annotSets.setSelectedItem(annotSetName);
0350     else
0351       annotSets.setSelectedIndex(0);
0352 
0353       //annotSetSelectionChanged();
0354   }
0355 
0356   /**Called when the content of the document has changed through an edit
0357    * operation.
0358    */
0359   public void contentEdited(gate.event.DocumentEvent e) {
0360     //ignore
0361   }
0362 
0363   public void annotationAdded(AnnotationSetEvent ase) {
0364     // ignore
0365   }
0366 
0367   public void annotationRemoved(AnnotationSetEvent ase) {
0368     Annotation delAnnot = ase.getAnnotation();
0369     Integer id = delAnnot.getId();
0370     Map matchesMap = null;
0371     Object matchesMapObject = document.getFeatures().get(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME);
0372     if(!(matchesMapObject instanceof Map)) {
0373       // no need to do anything
0374       // and return
0375       return;
0376     }
0377 
0378 
0379     matchesMap = (MapmatchesMapObject;
0380 
0381     if(matchesMap == null)
0382       return;
0383 
0384     Set keySet = matchesMap.keySet();
0385     if(keySet == null)
0386       return;
0387 
0388     Iterator iter = keySet.iterator();
0389     boolean found = false;
0390     while(iter.hasNext()) {
0391       String currSet = (Stringiter.next();
0392       java.util.List matches = (java.util.ListmatchesMap.get(currSet);
0393       if(matches == null || matches.size() == 0)
0394         continue;
0395       else {
0396         for(int i=0;i<matches.size();i++) {
0397           ArrayList ids = (ArrayListmatches.get(i);
0398           if(ids.contains(id)) {
0399             // found
0400             // so remove this
0401             found = true;
0402             ids.remove(id);
0403             matches.set(i, ids);
0404             break;
0405           }
0406         }
0407         if(found) {
0408           matchesMap.put(currSet, matches);
0409           explicitCall = true;
0410           document.getFeatures().put(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME,
0411                                      matchesMap);
0412           explicitCall = false;
0413           break;
0414         }
0415       }
0416     }
0417     if(found)
0418       featureMapUpdated();
0419   }
0420 
0421   /**
0422    * Called when features are changed outside the co-refEditor
0423    */
0424   public void featureMapUpdated() {
0425 
0426     if (explicitCall)
0427       return;
0428 
0429     // we would first save the current settings
0430     // 1. Current AnnotSet
0431     // 2. Current AnnotType
0432     // 3. ShowAnnotation Status
0433     String currentAnnotSet = (StringannotSets.getSelectedItem();
0434     String currentAnnotType = (StringannotTypes.getSelectedItem();
0435     boolean currentShowAnnotationStatus = showAnnotations.isSelected();
0436 
0437     // there is some change in the featureMap
0438     Map matchesMap = null;
0439     Object matchesMapObject = document.getFeatures().get(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME);
0440     if(!(matchesMapObject instanceof Map)) {
0441       // no need to do anything
0442       // and return
0443       reinitAllVariables();
0444       explicitCall = false;
0445       annotSets.setSelectedIndex(0);
0446       return;
0447     }
0448 
0449     matchesMap = (MapmatchesMapObject;
0450 
0451     if (matchesMap == null) {
0452       reinitAllVariables();
0453       explicitCall = false;
0454       annotSets.setSelectedIndex(0);
0455       return;
0456     }
0457 
0458     //AnnotationSetName --> List of ArrayLists
0459     //each ArrayList contains Ids of related annotations
0460     Iterator setIter = matchesMap.keySet().iterator();
0461     HashMap annotSetsNamesMap = new HashMap();
0462     for (int i = 0; i < annotSets.getItemCount(); i++) {
0463       annotSetsNamesMap.put( (StringannotSets.getItemAt(i)new Boolean(false));
0464     }
0465     outer:while (setIter.hasNext()) {
0466       String currentSet = (StringsetIter.next();
0467       java.util.List matches = (java.util.ListmatchesMap.get(currentSet);
0468       currentSet = (currentSet == null? DEFAULT_ANNOTSET_NAME : currentSet;
0469 
0470       if (matches == null)
0471         continue;
0472 
0473       AnnotationSet currAnnotSet = getAnnotationSet(currentSet);
0474       annotSetsNamesMap.put(currentSet, new Boolean(true));
0475 
0476       Iterator entitiesIter = matches.iterator();
0477       //each entity is a list of annotation IDs
0478 
0479       if (corefAnnotationSetNodesMap.get(currentSet== null) {
0480         // we need to create the node for this
0481         if (currentSet.equals(DEFAULT_ANNOTSET_NAME)) {
0482           corefAnnotationSetNodesMap.put(DEFAULT_ANNOTSET_NAME,
0483                                          createChain(document.getAnnotations()true));
0484         }
0485         else {
0486           corefAnnotationSetNodesMap.put(currentSet,
0487                                          createChain(document.getAnnotations(
0488               currentSet)false));
0489         }
0490         continue outer;
0491       }
0492 
0493       HashMap chains = (HashMapcorefChains.get(corefAnnotationSetNodesMap.get(currentSet));
0494       HashMap visitedList = new HashMap();
0495 
0496       if (chains != null) {
0497         Iterator chainsList = chains.keySet().iterator();
0498 
0499         // intially no chainHead is visited
0500         while (chainsList.hasNext()) {
0501           visitedList.put( (CorefTreeNodechainsList.next()new Boolean(false));
0502         }
0503 
0504         // now we need to search for the chainHead of each group
0505         ArrayList idsToRemove = new ArrayList();
0506         while (entitiesIter.hasNext()) {
0507           ArrayList ids = (ArrayListentitiesIter.next();
0508           if (ids == null || ids.size() == 0) {
0509             idsToRemove.add(ids);
0510             continue;
0511           }
0512 
0513           CorefTreeNode chainHead = null;
0514           for (int i = 0; i < ids.size(); i++) {
0515             Integer id = (Integerids.get(i);
0516             // now lets find out the headnode for this, if it is available
0517             chainHead = findOutTheChainHead(currAnnotSet.get(id), currentSet);
0518             if (chainHead != null) {
0519               visitedList.put(chainHead, new Boolean(true));
0520               break;
0521             }
0522           }
0523 
0524           if (chainHead != null) {
0525             // we found the chainHead for this
0526             // so we would replace the ids
0527             // but before that we would check if chainHead should be replaced
0528             Annotation longestAnn = findOutTheLongestAnnotation(ids, getAnnotationSet(currentSet));
0529             if (getString(longestAnn).equals(chainHead.toString())) {
0530               chains.put(chainHead, ids);
0531               corefChains.put(corefAnnotationSetNodesMap.get(currentSet),
0532                               chains);
0533             }
0534             else {
0535               // we first check if new longestAnnotation String is already available as some other chain Node head
0536               if (currentColors.containsKey(getString(longestAnn))) {
0537                 // yes one chainHead with this string already exists
0538                 // so we need to merge them together
0539                 String longestString = getString(longestAnn);
0540                 CorefTreeNode tempChainHead = findOutChainNode(longestString, currentSet);
0541                 // now all the ids under current chainHead should be placed under the tempChainHead
0542                 ArrayList tempIds = (ArrayListchains.get(tempChainHead);
0543                 ArrayList currentChainHeadIds = (ArrayListchains.get(
0544                     chainHead);
0545                 // so lets merge them
0546                 tempIds.addAll(currentChainHeadIds);
0547 
0548                 // and update the chains
0549                 chains.remove(chainHead);
0550                 chains.put(tempChainHead, tempIds);
0551                 corefChains.put(corefAnnotationSetNodesMap.get(currentSet),
0552                                 chains);
0553                 visitedList.put(chainHead, new Boolean(false));
0554                 visitedList.put(tempChainHead, new Boolean(true));
0555 
0556               }
0557               else {
0558                 String previousString = chainHead.toString();
0559                 String newString = getString(longestAnn);
0560                 chainHead.setUserObject(newString);
0561 
0562                 // we need to change the colors
0563                 Color color = (ColorcurrentColors.get(previousString);
0564                 currentColors.remove(previousString);
0565                 currentColors.put(newString, color);
0566                 colorChainsMap.put(newString, currentColors);
0567 
0568                 // we need to change the selections
0569                 Boolean val = (BooleancurrentSelections.get(previousString);
0570                 currentSelections.remove(previousString);
0571                 currentSelections.put(newString, val);
0572                 selectionChainsMap.put(newString, currentSelections);
0573 
0574                 chains.put(chainHead, ids);
0575                 corefChains.put(corefAnnotationSetNodesMap.get(currentSet),
0576                                 chains);
0577               }
0578             }
0579           }
0580           else {
0581             // this is something new addition
0582             // so we need to create a new chainNode
0583             // this is the new chain
0584             // get the current annotSetNode
0585             CorefTreeNode annotSetNode = (CorefTreeNode)
0586                                          corefAnnotationSetNodesMap.get(
0587                 currentSet);
0588 
0589             // we need to find out the longest string annotation
0590             AnnotationSet actSet = getAnnotationSet(currentSet);
0591 
0592             Annotation ann = findOutTheLongestAnnotation(ids, getAnnotationSet(currentSet));
0593             // so before creating a new chainNode we need to find out if
0594             // any of the chainNodes has the same string that of this chainNode
0595             HashMap tempSelection = (HashMapselectionChainsMap.get(
0596                 currentSet);
0597             CorefTreeNode chainNode = null;
0598             if (tempSelection.containsKey(getString(ann))) {
0599               chainNode = findOutChainNode(getString(ann), currentSet);
0600 
0601               // ArrayList matches
0602               HashMap newHashMap = (HashMapcorefChains.get(annotSetNode);
0603               newHashMap.put(chainNode, ids);
0604               corefChains.put(annotSetNode, newHashMap);
0605 
0606               visitedList.put(chainNode, new Boolean(true));
0607             }
0608             else {
0609               // create the new chainNode
0610               chainNode = new CorefTreeNode(getString(ann), false,
0611                                             CorefTreeNode.CHAIN_NODE);
0612 
0613               // add this to tree
0614               annotSetNode.add(chainNode);
0615               corefAnnotationSetNodesMap.put(currentSet, annotSetNode);
0616 
0617               // ArrayList matches
0618               HashMap newHashMap = (HashMapcorefChains.get(annotSetNode);
0619               newHashMap.put(chainNode, ids);
0620               corefChains.put(annotSetNode, newHashMap);
0621 
0622               boolean selectionValue = false;
0623               if(currentAnnotSet.equals(currentSet))
0624                 selectionValue = true;
0625 
0626               // entry into the selection
0627               tempSelection.put(chainNode.toString()new Boolean(selectionValue));
0628               selectionChainsMap.put(currentSet, tempSelection);
0629 
0630               // entry into the colors
0631               float components[] = colorGenerator.getNextColor().getComponents(null);
0632               Color color = new Color(components[0],
0633                                       components[1],
0634                                       components[2],
0635                                       0.5f);
0636               HashMap tempColors = (HashMapcolorChainsMap.get(currentSet);
0637               tempColors.put(chainNode.toString(), color);
0638               colorChainsMap.put(annotSets.getSelectedItem(), tempColors);
0639             }
0640           }
0641         }
0642 
0643         // ok we need to remove Idsnow
0644         Iterator removeIter = idsToRemove.iterator();
0645         while (removeIter.hasNext()) {
0646           explicitCall = true;
0647           ArrayList ids = (ArrayListremoveIter.next();
0648           matches.remove(ids);
0649           String set = currentSet.equals(DEFAULT_ANNOTSET_NAMEnull :
0650                        currentSet;
0651           matchesMap.put(set, matches);
0652           explicitCall = false;
0653         }
0654         explicitCall = true;
0655         document.getFeatures().put(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME,
0656                                    matchesMap);
0657         explicitCall = false;
0658 
0659         // here we need to find out the chainNodes those are no longer needed
0660         Iterator visitedListIter = visitedList.keySet().iterator();
0661         while (visitedListIter.hasNext()) {
0662           CorefTreeNode chainNode = (CorefTreeNodevisitedListIter.next();
0663           if (( (BooleanvisitedList.get(chainNode)).booleanValue()) {
0664             // yes this should be deleted
0665             CorefTreeNode annotSetNode = (CorefTreeNode)
0666                                          corefAnnotationSetNodesMap.get(
0667                 currentSet);
0668 
0669             // remove from the tree
0670             annotSetNode.remove(chainNode);
0671             corefAnnotationSetNodesMap.put(currentSet, annotSetNode);
0672 
0673             // ArrayList matches
0674             HashMap newHashMap = (HashMapcorefChains.get(annotSetNode);
0675             newHashMap.remove(chainNode);
0676             corefChains.put(annotSetNode, newHashMap);
0677 
0678             // remove from the selections
0679             HashMap tempSelection = (HashMapselectionChainsMap.get(
0680                 currentSet);
0681             tempSelection.remove(chainNode.toString());
0682             selectionChainsMap.put(currentSet, tempSelection);
0683 
0684             // remove from the colors
0685             HashMap tempColors = (HashMapcolorChainsMap.get(currentSet);
0686             tempColors.remove(chainNode.toString());
0687             colorChainsMap.put(currentSet, currentColors);
0688           }
0689         }
0690       }
0691     }
0692 
0693     Iterator tempIter = annotSetsNamesMap.keySet().iterator();
0694     while (tempIter.hasNext()) {
0695       String currentSet = (StringtempIter.next();
0696       if (( (BooleanannotSetsNamesMap.get(currentSet)).booleanValue()) {
0697         String annotSet = currentSet;
0698         // find out the currently Selected annotationSetName
0699         String annotSetName = (StringannotSets.getSelectedItem();
0700         // remove it from the main data store
0701         corefChains.remove(corefAnnotationSetNodesMap.get(annotSet));
0702         // remove it from the main data store
0703         corefAnnotationSetNodesMap.remove(annotSet);
0704         // remove it from the annotationSetModel (combobox)
0705         annotSetsModel.removeElement(annotSet);
0706         annotSets.setModel(annotSetsModel);
0707         annotSets.updateUI();
0708         // remove it from the colorChainMap
0709         colorChainsMap.remove(annotSet);
0710         // remove it from the selectionChainMap
0711         selectionChainsMap.remove(annotSet);
0712       }
0713     }
0714 
0715     if (annotSetsModel.getSize() == 0) {
0716       // no annotationSet to display
0717       // so set visible false
0718       if (popupWindow != null && popupWindow.isVisible()) {
0719         popupWindow.setVisible(false);
0720       }
0721       corefTree.setVisible(false);
0722 
0723       // remove all highlights
0724       ArrayList allHighlights = new ArrayList();
0725       if(typeSpecificHighlightedTags != null)
0726         allHighlights.addAll(typeSpecificHighlightedTags);
0727       if(highlightedTags != null) {
0728         Iterator iter = highlightedTags.values().iterator();
0729         while(iter.hasNext()) {
0730           ArrayList highlights = (ArrayListiter.next();
0731           allHighlights.addAll(highlights);
0732         }
0733       }
0734       for(int i=0;i<allHighlights.size();i++) {
0735         highlighter.removeHighlight(allHighlights.get(i));
0736       }
0737 
0738       //highlighter.removeAllHighlights();
0739       highlightedTags = null;
0740       typeSpecificHighlightedTags = null;
0741       return;
0742     }
0743     else {
0744 
0745       if (popupWindow != null && popupWindow.isVisible()) {
0746         popupWindow.setVisible(false);
0747       }
0748 
0749       // remove all highlights
0750       ArrayList allHighlights = new ArrayList();
0751       if(typeSpecificHighlightedTags != null)
0752         allHighlights.addAll(typeSpecificHighlightedTags);
0753       if(highlightedTags != null) {
0754         Iterator iter = highlightedTags.values().iterator();
0755         while(iter.hasNext()) {
0756           ArrayList highlights = (ArrayListiter.next();
0757           allHighlights.addAll(highlights);
0758         }
0759       }
0760       for (int i = 0; i < allHighlights.size(); i++) {
0761         highlighter.removeHighlight(allHighlights.get(i));
0762       }
0763 
0764       //highlighter.removeAllHighlights();
0765       highlightedTags = null;
0766       typeSpecificHighlightedTags = null;
0767       if (currentAnnotSet != null) {
0768         annotSets.setSelectedItem(currentAnnotSet);
0769         currentSelections = (HashMapselectionChainsMap.get(currentAnnotSet);
0770         currentColors = (HashMapcolorChainsMap.get(currentAnnotSet);
0771         highlightAnnotations();
0772 
0773         showAnnotations.setSelected(currentShowAnnotationStatus);
0774         if (currentAnnotType != null)
0775           annotTypes.setSelectedItem(currentAnnotType);
0776         else
0777         if (annotTypes.getModel().getSize() 0) {
0778           annotTypes.setSelectedIndex(0);
0779         }
0780       }
0781       else {
0782         explicitCall = false;
0783         annotSets.setSelectedIndex(0);
0784       }
0785     }
0786   }
0787 
0788   /**
0789    * ActionPerformed Activity
0790    @param ae
0791    */
0792   public void actionPerformed(ActionEvent ae) {
0793     // when annotationSet value changes
0794     if (ae.getSource() == annotSets) {
0795       if (!explicitCall) {
0796         annotSetSelectionChanged();
0797       }
0798     }
0799     else if (ae.getSource() == showAnnotations) {
0800       if (!explicitCall) {
0801         showTypeWiseAnnotations();
0802       }
0803     }
0804     else if (ae.getSource() == annotTypes) {
0805       if (!explicitCall) {
0806         if (typeSpecificHighlightedTags != null) {
0807           for (int i = 0; i < typeSpecificHighlightedTags.size(); i++) {
0808             highlighter.removeHighlight(typeSpecificHighlightedTags.get(i));
0809           }
0810         }
0811         typeSpecificHighlightedTags = null;
0812         showTypeWiseAnnotations();
0813       }
0814     }
0815   }
0816 
0817   /**
0818    * When user preses the show Toggle button, this will show up annotations
0819    * of selected Type from selected AnnotationSet
0820    */
0821   private void showTypeWiseAnnotations() {
0822     if (typeSpecificHighlightedTags == null) {
0823       highlightedTypeAnnots = new ArrayList();
0824       typeSpecificHighlightedTags = new ArrayList();
0825     }
0826 
0827     if (showAnnotations.isSelected()) {
0828       // get the annotationsSet and its type
0829       AnnotationSet set = getAnnotationSet( (StringannotSets.getSelectedItem());
0830       String type = (StringannotTypes.getSelectedItem();
0831       if (type == null) {
0832         try {
0833           JOptionPane.showMessageDialog(MainFrame.getInstance(),
0834                                         "No annotation type found to display");
0835         }
0836         catch (Exception e) {
0837           e.printStackTrace();
0838         }
0839         showAnnotations.setSelected(false);
0840         return;
0841       }
0842 
0843       Color color = AnnotationSetsView.getColor(getAnnotationSet((String)annotSets.getSelectedItem()).getName(),type);
0844       if (type != null) {
0845         AnnotationSet typeSet = set.get(type);
0846         Iterator<Annotation> iter = typeSet.iterator();
0847         while (iter.hasNext()) {
0848           Annotation ann = iter.next();
0849           highlightedTypeAnnots.add(ann);
0850           try {
0851             typeSpecificHighlightedTags.add(highlighter.addHighlight(ann.
0852                 getStartNode().
0853                 getOffset().intValue(),
0854                 ann.getEndNode().getOffset().intValue(),
0855                 new DefaultHighlighter.
0856                 DefaultHighlightPainter(color)));
0857           }
0858           catch (Exception e) {
0859             e.printStackTrace();
0860           }
0861           //typeSpecificHighlightedTags.add(textView.addHighlight(ann, getAnnotationSet((String)annotSets.getSelectedItem()),color));
0862         }
0863       }
0864     }
0865     else {
0866       for (int i = 0; i < typeSpecificHighlightedTags.size(); i++) {
0867         //textView.removeHighlight(typeSpecificHighlightedTags.get(i));
0868         highlighter.removeHighlight(typeSpecificHighlightedTags.get(i));
0869       }
0870       typeSpecificHighlightedTags = new ArrayList();
0871       highlightedTypeAnnots = new ArrayList();
0872       highlightedTypeAnnotsOffsets = null;
0873     }
0874 
0875     // This is to make process faster.. instead of accessing each annotation and
0876     // its offset, we create an array with its annotation offsets to search faster
0877     Collections.sort(highlightedTypeAnnots, new gate.util.OffsetComparator());
0878     highlightedTypeAnnotsOffsets = new int[highlightedTypeAnnots.size() 2];
0879     for (int i = 0, j = 0; j < highlightedTypeAnnots.size(); i += 2, j++) {
0880       Annotation ann1 = (AnnotationhighlightedTypeAnnots.get(j);
0881       highlightedTypeAnnotsOffsets[i= ann1.getStartNode().getOffset().
0882                                         intValue();
0883       highlightedTypeAnnotsOffsets[i +
0884           1= ann1.getEndNode().getOffset().intValue();
0885     }
0886 
0887   }
0888 
0889   /**
0890    * Returns annotation Set
0891    @param annotSet
0892    @return
0893    */
0894   private AnnotationSet getAnnotationSet(String annotSet) {
0895     return (annotSet.equals(DEFAULT_ANNOTSET_NAME)) ? document.getAnnotations() :
0896         document.getAnnotations(annotSet);
0897   }
0898 
0899   /**
0900    * When annotationSet selection changes
0901    */
0902   private void annotSetSelectionChanged() {
0903     if (annotSets.getModel().getSize() == 0) {
0904       if (popupWindow != null && popupWindow.isVisible()) {
0905         popupWindow.setVisible(false);
0906       }
0907       corefTree.setVisible(false);
0908       return;
0909     }
0910 
0911     String currentAnnotSet = (StringannotSets.getSelectedItem();
0912     // get all the types of the currently Selected AnnotationSet
0913     if (currentAnnotSet == null)
0914       currentAnnotSet = (StringannotSets.getItemAt(0);
0915     AnnotationSet temp = getAnnotationSet(currentAnnotSet);
0916     Set types = temp.getAllTypes();
0917     annotTypesModel = new DefaultComboBoxModel();
0918     if (types != null) {
0919       annotTypesModel = new DefaultComboBoxModel(types.toArray());
0920     }
0921     annotTypes.setModel(annotTypesModel);
0922     annotTypes.updateUI();
0923 
0924     // and redraw the CorefTree
0925     if (rootNode.getChildCount() 0)
0926       rootNode.removeAllChildren();
0927 
0928     CorefTreeNode annotSetNode = (CorefTreeNodecorefAnnotationSetNodesMap.get(
0929         currentAnnotSet);
0930 
0931     if (annotSetNode != null) {
0932       rootNode.add(annotSetNode);
0933       currentSelections = (HashMapselectionChainsMap.get(currentAnnotSet);
0934       currentColors = (HashMapcolorChainsMap.get(currentAnnotSet);
0935       if (!corefTree.isVisible()) {
0936         if (popupWindow != null && popupWindow.isVisible()) {
0937           popupWindow.setVisible(false);
0938         }
0939         corefTree.setVisible(true);
0940       }
0941       corefTree.repaint();
0942       corefTree.updateUI();
0943 
0944     }
0945     else {
0946       corefTree.setVisible(false);
0947     }
0948   }
0949 
0950   /**
0951    * This will initialise the data
0952    */
0953   private void initData() {
0954 
0955     rootNode = new CorefTreeNode("Co-reference Data", true,
0956                                  CorefTreeNode.ROOT_NODE);
0957     corefChains = new HashMap();
0958     selectionChainsMap = new HashMap();
0959     currentSelections = new HashMap();
0960     colorChainsMap = new HashMap();
0961     currentColors = new HashMap();
0962     corefAnnotationSetNodesMap = new HashMap();
0963 
0964     // now we need to findout the chains
0965     // for the defaultAnnotationSet
0966     CorefTreeNode annotSetNode = createChain(document.getAnnotations()true);
0967     if (annotSetNode != null) {
0968       corefAnnotationSetNodesMap.put(DEFAULT_ANNOTSET_NAME, annotSetNode);
0969     }
0970 
0971     // and for the rest AnnotationSets
0972     Map annotSets = document.getNamedAnnotationSets();
0973     if (annotSets != null) {
0974       Iterator annotSetsIter = annotSets.keySet().iterator();
0975       while (annotSetsIter.hasNext()) {
0976         String annotSetName = (StringannotSetsIter.next();
0977         annotSetNode = createChain(document.getAnnotations(annotSetName)false);
0978         if (annotSetNode != null) {
0979           corefAnnotationSetNodesMap.put(annotSetName, annotSetNode);
0980         }
0981       }
0982     }
0983   }
0984 
0985   private CorefTreeNode createAnnotSetNode(AnnotationSet set, boolean isDefaultSet) {
0986     // create the node for setName
0987     String setName = isDefaultSet ? DEFAULT_ANNOTSET_NAME : set.getName();
0988     CorefTreeNode annotSetNode = new CorefTreeNode(setName, true,
0989         CorefTreeNode.ANNOTSET_NODE);
0990 
0991     // see if this setName available in the annotSets
0992     boolean found = false;
0993     for (int i = 0; i < annotSets.getModel().getSize(); i++) {
0994       if ( ( (StringannotSets.getModel().getElementAt(i)).equals(setName)) {
0995         found = true;
0996         break;
0997       }
0998     }
0999     if (!found) {
1000       explicitCall = true;
1001       annotSets.addItem(setName);
1002       explicitCall = false;
1003     }
1004 
1005     // the internal datastructure
1006     HashMap chainLinks = new HashMap();
1007     HashMap selectionMap = new HashMap();
1008     HashMap colorMap = new HashMap();
1009 
1010     corefChains.put(annotSetNode, chainLinks);
1011     selectionChainsMap.put(setName, selectionMap);
1012     colorChainsMap.put(setName, colorMap);
1013     return annotSetNode;
1014 
1015   }
1016 
1017   /**
1018    * Creates the internal data structure
1019    @param set
1020    */
1021   private CorefTreeNode createChain(AnnotationSet set, boolean isDefaultSet) {
1022 
1023     // create the node for setName
1024     String setName = isDefaultSet ? DEFAULT_ANNOTSET_NAME : set.getName();
1025     CorefTreeNode annotSetNode = new CorefTreeNode(setName, true,
1026         CorefTreeNode.ANNOTSET_NODE);
1027 
1028     // see if this setName available in the annotSets
1029     boolean found = false;
1030     for (int i = 0; i < annotSets.getModel().getSize(); i++) {
1031       if ( ( (StringannotSets.getModel().getElementAt(i)).equals(setName)) {
1032         found = true;
1033         break;
1034       }
1035     }
1036     if (!found) {
1037       explicitCall = true;
1038       annotSets.addItem(setName);
1039       explicitCall = false;
1040     }
1041 
1042     // the internal datastructure
1043     HashMap chainLinks = new HashMap();
1044     HashMap selectionMap = new HashMap();
1045     HashMap colorMap = new HashMap();
1046 
1047     // map for all the annotations with matches feature in it
1048     Map matchesMap = null;
1049     Object matchesMapObject = document.getFeatures().get(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME);
1050     if(matchesMapObject instanceof Map) {
1051       matchesMap = (MapmatchesMapObject;
1052     }
1053 
1054 
1055     // what if this map is null
1056     if (matchesMap == null) {
1057       corefChains.put(annotSetNode, chainLinks);
1058       selectionChainsMap.put(setName, selectionMap);
1059       colorChainsMap.put(setName, colorMap);
1060       return annotSetNode;
1061     }
1062 
1063     //AnnotationSetName --> List of ArrayLists
1064     //each ArrayList contains Ids of related annotations
1065     Iterator setIter = matchesMap.keySet().iterator();
1066     java.util.List matches1 = (java.util.ListmatchesMap.get(isDefaultSet ? null :
1067         setName);
1068     if (matches1 == null) {
1069       corefChains.put(annotSetNode, chainLinks);
1070       selectionChainsMap.put(setName, selectionMap);
1071       colorChainsMap.put(setName, colorMap);
1072       return annotSetNode;
1073     }
1074 
1075     Iterator tempIter = matches1.iterator();
1076 
1077     while (tempIter.hasNext()) {
1078       ArrayList matches = (ArrayListtempIter.next();
1079       int length = 0;
1080       int index = 0;
1081       if (matches == null)
1082         matches = new ArrayList();
1083 
1084       if (matches.size() && set.size() 0) {
1085 
1086         String longestString = getString((AnnotationfindOutTheLongestAnnotation(matches,
1087             set));
1088         // so this should become one of the tree node
1089         CorefTreeNode chainNode = new CorefTreeNode(longestString, false,
1090             CorefTreeNode.CHAIN_NODE);
1091         // and add it under the topNode
1092         annotSetNode.add(chainNode);
1093 
1094         // chainNode --> All related annotIds
1095         chainLinks.put(chainNode, matches);
1096         selectionMap.put(chainNode.toString()new Boolean(false));
1097         // and generate the color for this chainNode
1098         float components[] = colorGenerator.getNextColor().getComponents(null);
1099         Color color = new Color(components[0],
1100                                 components[1],
1101                                 components[2],
1102                                 0.5f);
1103         colorMap.put(chainNode.toString(), color);
1104       }
1105     }
1106 
1107     corefChains.put(annotSetNode, chainLinks);
1108     selectionChainsMap.put(setName, selectionMap);
1109     colorChainsMap.put(setName, colorMap);
1110     return annotSetNode;
1111   }
1112 
1113   /**
1114    * Given an annotation, this method returns the string of that annotation
1115    @param ann
1116    @return
1117    */
1118   public String getString(Annotation ann) {
1119     return document.getContent().toString().substring(ann.
1120         getStartNode().getOffset().intValue(),
1121         ann.getEndNode().getOffset().intValue());
1122   }
1123 
1124   /**
1125    * Removes the reference of this annotation from the current chain.
1126    @param annot annotation to remove
1127    @param chainHead co-reference chain to modify
1128    */
1129   public void removeChainReference(Annotation annot, CorefTreeNode chainHead) {
1130 
1131     // so we would find out the matches
1132     CorefTreeNode currentNode = chainHead;
1133     ArrayList ids = (ArrayList) ( (HashMap)
1134                                  corefChains.get(corefAnnotationSetNodesMap.get(
1135         annotSets.getSelectedItem()))).get(chainHead);
1136 
1137    String currentSet = (StringannotSets.getSelectedItem();
1138    currentSet = (currentSet.equals(DEFAULT_ANNOTSET_NAME)) null : currentSet;
1139 
1140     // we need to update the Co-reference document feature
1141     Map matchesMap = null;
1142     java.util.List matches = null;
1143     Object matchesMapObject = document.getFeatures().get(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME);
1144     if(matchesMapObject instanceof Map) {
1145       matchesMap = (MapmatchesMapObject;
1146       matches = (java.util.ListmatchesMap.get(currentSet);
1147     else {
1148       matchesMap = new HashMap();
1149     }
1150 
1151     if (matches == null)
1152       matches = new ArrayList();
1153 
1154     int index = matches.indexOf(ids);
1155     if (index != -1) {
1156       // yes found
1157       ids.remove(annot.getId());
1158       Annotation ann = findOutTheLongestAnnotation(ids,
1159           getAnnotationSet( (StringannotSets.getSelectedItem()));
1160 
1161       matches.set(index, ids);
1162       matchesMap.put(currentSet, matches);
1163       document.getFeatures().put(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME,
1164                                  matchesMap);
1165     }
1166   }
1167 
1168   /**
1169    * Given an annotation, this will find out the chainHead
1170    @param ann
1171    @return
1172    */
1173   private CorefTreeNode findOutTheChainHead(Annotation ann, String set) {
1174     HashMap chains = (HashMapcorefChains.get(corefAnnotationSetNodesMap.get(
1175         set));
1176     if (chains == null)
1177       return null;
1178     Iterator iter = chains.keySet().iterator();
1179     while (iter.hasNext()) {
1180       CorefTreeNode head = (CorefTreeNodeiter.next();
1181       if ( ( (ArrayListchains.get(head)).contains(ann.getId())) {
1182         return head;
1183       }
1184     }
1185     return null;
1186   }
1187 
1188   /**
1189    * This methods highlights the annotations
1190    */
1191   public void highlightAnnotations() {
1192 
1193     if (highlightedTags == null) {
1194       highlightedTags = new HashMap();
1195       highlightedChainAnnots = new ArrayList();
1196     }
1197 
1198     AnnotationSet annotSet = getAnnotationSet( (StringannotSets.
1199                                               getSelectedItem());
1200     CorefTreeNode annotSetNode = (CorefTreeNodecorefAnnotationSetNodesMap.get(
1201         annotSets.getSelectedItem());
1202     if (annotSetNode == null) {
1203       return;
1204     }
1205     HashMap chainMap = (HashMapcorefChains.get(annotSetNode);
1206     Iterator iter = chainMap.keySet().iterator();
1207 
1208     while (iter.hasNext()) {
1209       CorefTreeNode currentNode = (CorefTreeNodeiter.next();
1210       if ( ( (BooleancurrentSelections.get(currentNode.toString())).
1211           booleanValue()) {
1212         if (!highlightedTags.containsKey(currentNode)) {
1213           // find out the arrayList
1214           ArrayList ids = (ArrayListchainMap.get(currentNode);
1215           ArrayList highlighTag = new ArrayList();
1216           if (ids != null) {
1217             for (int i = 0; i < ids.size(); i++) {
1218               Annotation ann = annotSet.get( (Integerids.get(i));
1219               highlightedChainAnnots.add(ann);
1220               Color color = (ColorcurrentColors.get(currentNode.toString());
1221               try {
1222                 highlighTag.add(highlighter.addHighlight(ann.getStartNode().
1223                     getOffset().intValue(),
1224                     ann.getEndNode().getOffset().intValue(),
1225                     new DefaultHighlighter.
1226                     DefaultHighlightPainter(color)));
1227               }
1228               catch (Exception e) {
1229                 e.printStackTrace();
1230               }
1231               //highlighTag.add(textView.addHighlight(ann, getAnnotationSet((String) annotSets.getSelectedItem()), color));
1232             }
1233             highlightedTags.put(currentNode, highlighTag);
1234           }
1235         }
1236       }
1237       else {
1238         if (highlightedTags.containsKey(currentNode)) {
1239           ArrayList highlights = (ArrayListhighlightedTags.get(currentNode);
1240           for (int i = 0; i < highlights.size(); i++) {
1241             //textView.removeHighlight(highlights.get(i));
1242             highlighter.removeHighlight(highlights.get(i));
1243           }
1244           highlightedTags.remove(currentNode);
1245           ArrayList ids = (ArrayListchainMap.get(currentNode);
1246           if (ids != null) {
1247             for (int i = 0; i < ids.size(); i++) {
1248               Annotation ann = annotSet.get( (Integerids.get(i));
1249               highlightedChainAnnots.remove(ann);
1250             }
1251           }
1252         }
1253       }
1254     }
1255 
1256     // This is to make process faster.. instead of accessing each annotation and
1257     // its offset, we create an array with its annotation offsets to search faster
1258     Collections.sort(highlightedChainAnnots, new gate.util.OffsetComparator());
1259     highlightedChainAnnotsOffsets = new int[highlightedChainAnnots.size() 2];
1260     for (int i = 0, j = 0; j < highlightedChainAnnots.size(); i += 2, j++) {
1261       Annotation ann1 = (AnnotationhighlightedChainAnnots.get(j);
1262       highlightedChainAnnotsOffsets[i= ann1.getStartNode().getOffset().
1263                                          intValue();
1264       highlightedChainAnnotsOffsets[i +
1265           1= ann1.getEndNode().getOffset().intValue();
1266     }
1267   }
1268 
1269   protected void registerHooks() {
1270     textPane.addMouseListener(textPaneMouseListener);
1271     textPane.addMouseMotionListener(textPaneMouseListener);
1272 
1273   }
1274 
1275   protected void unregisterHooks() {
1276     textPane.removeMouseListener(textPaneMouseListener);
1277     textPane.removeMouseMotionListener(textPaneMouseListener);
1278   }
1279 
1280   public Component getGUI() {
1281     return mainPanel;
1282   }
1283 
1284   public int getType() {
1285     return VERTICAL;
1286   }
1287 
1288   //**********************************************
1289    // MouseListener and MouseMotionListener Methods
1290    //***********************************************
1291 
1292     protected class TextPaneMouseListener
1293         extends MouseInputAdapter {
1294 
1295       public TextPaneMouseListener() {
1296         chainToolTipTimer.setRepeats(false);
1297         newCorefActionTimer.setRepeats(false);
1298       }
1299 
1300       public void mouseMoved(MouseEvent me) {
1301         int textLocation = textPane.viewToModel(me.getPoint());
1302         chainToolTipAction.setTextLocation(textLocation);
1303         chainToolTipAction.setMousePointer(me.getPoint());
1304         chainToolTipTimer.restart();
1305 
1306         newCorefAction.setTextLocation(textLocation);
1307         newCorefAction.setMousePointer(me.getPoint());
1308         newCorefActionTimer.restart();
1309       }
1310     }
1311 
1312   public void mouseClicked(MouseEvent me) {
1313     if (popupWindow != null && popupWindow.isVisible()) {
1314       popupWindow.setVisible(false);
1315     }
1316   }
1317 
1318   public CorefTreeNode findOutChainNode(String chainNodeString, String set) {
1319     if (corefChains == null || corefAnnotationSetNodesMap == null) {
1320       return null;
1321     }
1322     HashMap chains = (HashMapcorefChains.get(corefAnnotationSetNodesMap.get(set));
1323     if (chains == null) {
1324       return null;
1325     }
1326     Iterator iter = chains.keySet().iterator();
1327     while (iter.hasNext()) {
1328       CorefTreeNode currentNode = (CorefTreeNodeiter.next();
1329       if (currentNode.toString().equals(chainNodeString))
1330         return currentNode;
1331     }
1332     return null;
1333   }
1334 
1335   /**
1336    * When user hovers over the annotations which have been highlighted by
1337    * show button
1338    */
1339   protected class NewCorefAction
1340       implements ActionListener {
1341 
1342     int textLocation;
1343     Point mousePoint;
1344     JLabel label = new JLabel();
1345     JPanel panel = new JPanel();
1346     JPanel subPanel = new JPanel();
1347     String field = "";
1348     JButton add = new JButton("OK");
1349     JButton cancel = new JButton("Cancel");
1350     JComboBox list = new JComboBox();
1351     JPanel mainPanel = new JPanel();
1352     JPopupMenu popup1 = new JPopupMenu();
1353     ListEditor listEditor = null;
1354     ComboBoxModel model = new DefaultComboBoxModel();
1355     boolean firstTime = true;
1356 
1357     public NewCorefAction() {
1358       popupWindow = new JWindow(SwingUtilities.getWindowAncestor(textView.
1359           getGUI()));
1360       popupWindow.setBackground(UIManager.getLookAndFeelDefaults().
1361                                 getColor("ToolTip.background"));
1362       mainPanel.setLayout(new BorderLayout());
1363       mainPanel.setOpaque(true);
1364       mainPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
1365       mainPanel.setBackground(UIManager.getLookAndFeelDefaults().
1366                               getColor("ToolTip.background"));
1367       popupWindow.setContentPane(mainPanel);
1368 
1369       panel.setLayout(new BorderLayout());
1370       panel.setOpaque(false);
1371       panel.add(new JScrollPane(list), BorderLayout.CENTER);
1372 
1373       subPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
1374       subPanel.add(add);
1375       subPanel.add(cancel);
1376       subPanel.setOpaque(false);
1377       panel.add(subPanel, BorderLayout.SOUTH);
1378       mainPanel.add(label, BorderLayout.NORTH);
1379       mainPanel.add(panel, BorderLayout.CENTER);
1380 
1381       // and finally load the data for the list
1382       AddAction action = new AddAction();
1383       add.addActionListener(action);
1384       cancel.addActionListener(action);
1385       listEditor = new ListEditor(action);
1386       list.setMaximumRowCount(5);
1387       list.setEditable(true);
1388       list.setEditor(listEditor);
1389       list.setModel(model);
1390     }
1391 
1392     public void actionPerformed(ActionEvent ae) {
1393       int index = -1;
1394       if (highlightedChainAnnotsOffsets != null) {
1395         for (int i = 0; i < highlightedChainAnnotsOffsets.length; i += 2) {
1396           if (textLocation >= highlightedChainAnnotsOffsets[i&&
1397               textLocation <= highlightedChainAnnotsOffsets[i + 1]) {
1398             index = (i == 0? i : i / 2;
1399             break;
1400           }
1401         }
1402       }
1403 
1404       // yes it is put on highlighted so show the annotationType
1405       if (highlightedChainAnnotsOffsets != null &&
1406           index < highlightedChainAnnotsOffsets.length && index >= 0) {
1407         return;
1408       }
1409 
1410       if (highlightedTypeAnnotsOffsets != null) {
1411         for (int i = 0; i < highlightedTypeAnnotsOffsets.length; i += 2) {
1412           if (textLocation >= highlightedTypeAnnotsOffsets[i&&
1413               textLocation <= highlightedTypeAnnotsOffsets[i + 1]) {
1414             index = (i == 0? i : i / 2;
1415             break;
1416           }
1417         }
1418       }
1419 
1420       // yes it is put on highlighted so show the annotationType
1421       if (highlightedTypeAnnotsOffsets != null &&
1422           index < highlightedTypeAnnotsOffsets.length && index >= 0) {
1423         textPane.removeAll();
1424         annotToConsiderForChain = (AnnotationhighlightedTypeAnnots.get(index);
1425         // now check if this annotation is already linked with something
1426         CorefTreeNode headNode = findOutTheChainHead(annotToConsiderForChain, (StringannotSets.getSelectedItem());
1427         if (headNode != null) {
1428           popup1 = new JPopupMenu();
1429           popup1.setBackground(UIManager.getLookAndFeelDefaults().
1430                                getColor("ToolTip.background"));
1431           JLabel label1 = new JLabel("Annotation co-referenced to : \"" +
1432                                      headNode.toString() "\"");
1433           popup1.setLayout(new FlowLayout());
1434           popup1.add(label1);
1435           if (popupWindow != null && popupWindow.isVisible()) {
1436             popupWindow.setVisible(false);
1437           }
1438           popup1.setVisible(true);
1439           popup1.show(textPane, (intmousePoint.getX()(intmousePoint.getY());
1440         }
1441         else {
1442           popupWindow.setVisible(false);
1443           ArrayList set = new ArrayList(currentSelections.keySet());
1444           Collections.sort(set);
1445           set.add(0"[New Chain]");
1446           model = new DefaultComboBoxModel(set.toArray());
1447           list.setModel(model);
1448           listEditor.setItem("");
1449           label.setText("Add \"" + getString(annotToConsiderForChain+
1450                         "\" to ");
1451           Point topLeft = textPane.getLocationOnScreen();
1452           int x = topLeft.x + (intmousePoint.getX();
1453           int y = topLeft.y + (intmousePoint.getY();
1454           popupWindow.setLocation(x, y);
1455           if (popup1.isVisible()) {
1456             popup1.setVisible(false);
1457           }
1458           popupWindow.pack();
1459           popupWindow.setVisible(true);
1460           listEditor.requestFocus();
1461 
1462           if (firstTime) {
1463             firstTime = false;
1464             popupWindow.pack();
1465             popupWindow.repaint();
1466             listEditor.requestFocus();
1467           }
1468         }
1469       }
1470     }
1471 
1472     public void setTextLocation(int textLocation) {
1473       this.textLocation = textLocation;
1474     }
1475 
1476     public void setMousePointer(Point point) {
1477       this.mousePoint = point;
1478     }
1479 
1480     /** Custom Editor for the ComboBox to enable key events */
1481     private class ListEditor
1482         extends KeyAdapter
1483         implements ComboBoxEditor {
1484       JTextField myField = new JTextField(20);
1485       AddAction action = null;
1486       Vector myList = new Vector();
1487 
1488       public ListEditor(AddAction action) {
1489         this.action = action;
1490         myField.addKeyListener(this);
1491       }
1492 
1493       public void addActionListener(ActionListener al) {
1494         myField.addActionListener(al);
1495       }
1496 
1497       public void removeActionListener(ActionListener al) {
1498         myField.removeActionListener(al);
1499       }
1500 
1501       public Component getEditorComponent() {
1502         return myField;
1503       }
1504 
1505       public Object getItem() {
1506         return myField.getText();
1507       }
1508 
1509       public void selectAll() {
1510         if (myField.getText() != null && myField.getText().length() 0) {
1511           myField.setSelectionStart(0);
1512           myField.setSelectionEnd(myField.getText().length());
1513         }
1514       }
1515 
1516       public void setItem(Object item) {
1517         myField.setText( (Stringitem);
1518         field = myField.getText();
1519       }
1520 
1521       public void requestFocus() {
1522         myField.requestFocus();
1523       }
1524 
1525       public void keyReleased(KeyEvent ke) {
1526         if (myField.getText() == null) {
1527           myField.setText("");
1528           field = myField.getText();
1529         }
1530 
1531         if (ke.getKeyCode() == KeyEvent.VK_DOWN) {
1532           if (myList.size() == 1) {
1533             myField.setText( (StringmyList.get(0));
1534           }
1535           else if (list.getSelectedIndex() < list.getModel().getSize() 1) {
1536             list.setSelectedIndex(list.getSelectedIndex());
1537             myField.setText( (Stringlist.getSelectedItem());
1538           }
1539           field = myField.getText();
1540           myField.requestFocus();
1541           return;
1542         }
1543         else if (ke.getKeyCode() == KeyEvent.VK_UP) {
1544           if (list.getSelectedIndex() 0) {
1545             list.setSelectedIndex(list.getSelectedIndex());
1546           }
1547           myField.setText( (Stringlist.getSelectedItem());
1548           field = myField.getText();
1549           return;
1550         }
1551         else if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
1552           field = myField.getText();
1553           action.actionPerformed(new ActionEvent(add,
1554                                                  ActionEvent.ACTION_PERFORMED,
1555                                                  "add"));
1556           return;
1557         }
1558         else if (ke.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
1559         }
1560         else if (Character.isJavaIdentifierPart(ke.getKeyChar()) ||
1561                  Character.isSpaceChar(ke.getKeyChar()) ||
1562                  Character.isDefined(ke.getKeyChar())) {
1563         }
1564         else {
1565           return;
1566         }
1567 
1568         String startWith = myField.getText();
1569         myList = new Vector();
1570         ArrayList set = new ArrayList(currentSelections.keySet());
1571         Collections.sort(set);
1572         set.add(0"[New Chain]");
1573         boolean first = true;
1574         for (int i = 0; i < set.size(); i++) {
1575           String currString = (Stringset.get(i);
1576           if (currString.toLowerCase().startsWith(startWith.toLowerCase())) {
1577             if (first) {
1578               myField.setText(currString.substring(0, startWith.length()));
1579               first = false;
1580             }
1581             myList.add(currString);
1582           }
1583         }
1584         ComboBoxModel model = new DefaultComboBoxModel(myList);
1585         list.setModel(model);
1586         myField.setText(startWith);
1587         field = myField.getText();
1588         list.showPopup();
1589       }
1590     }
1591 
1592     private class AddAction
1593         extends AbstractAction {
1594       public void actionPerformed(ActionEvent ae) {
1595         if (ae.getSource() == cancel) {
1596           popupWindow.setVisible(false);
1597           return;
1598         }
1599         else if (ae.getSource() == add) {
1600           if (field.length() == 0) {
1601             try {
1602               JOptionPane.showMessageDialog(MainFrame.getInstance(),
1603                                             "No Chain Selected",
1604                                             "New Chain - Error",
1605                                             JOptionPane.ERROR_MESSAGE);
1606             }
1607             catch (Exception e) {
1608               e.printStackTrace();
1609             }
1610             return;
1611           }
1612           else {
1613             // we want to add this
1614             // now first find out the annotation
1615             Annotation ann = annotToConsiderForChain;
1616             if (ann == null)
1617               return;
1618             // yes it is available
1619             // find out the CorefTreeNode for the chain under which it is to be inserted
1620             if (field.equals("[New Chain]")) {
1621               // we want to add this
1622               // now first find out the annotation
1623               if (ann == null)
1624                 return;
1625               CorefTreeNode chainNode = findOutChainNode(getString(ann)(StringannotSets.getSelectedItem());
1626               if (chainNode != null) {
1627                 try {
1628                   JOptionPane.showMessageDialog(MainFrame.getInstance(),
1629                                                 "Chain with " + getString(ann+
1630                                                 " title already exists",
1631                                                 "New Chain - Error",
1632                                                 JOptionPane.ERROR_MESSAGE);
1633                 }
1634                 catch (Exception e) {
1635                   e.printStackTrace();
1636                 }
1637                 return;
1638               }
1639 
1640               popupWindow.setVisible(false);
1641 
1642               String currentSet = (StringannotSets.getSelectedItem();
1643               currentSet = (currentSet.equals(DEFAULT_ANNOTSET_NAME)) null :
1644                            currentSet;
1645 
1646               Map matchesMap = null;
1647               Object matchesMapObject = document.getFeatures().get(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME);
1648               if(matchesMapObject instanceof Map) {
1649                 matchesMap = (MapmatchesMapObject;
1650               }
1651 
1652               if (matchesMap == null) {
1653                 matchesMap = new HashMap();
1654               }
1655 
1656               java.util.List matches = (java.util.ListmatchesMap.get(
1657                   currentSet);
1658               ArrayList tempList = new ArrayList();
1659               tempList.add(ann.getId());
1660               if (matches == null)
1661                 matches = new ArrayList();
1662               matches.add(tempList);
1663               matchesMap.put(currentSet, matches);
1664               document.getFeatures().put(ANNIEConstants.
1665                                          DOCUMENT_COREF_FEATURE_NAME,
1666                                          matchesMap);
1667               return;
1668             }
1669 
1670             CorefTreeNode chainNode = findOutChainNode(field, (StringannotSets.getSelectedItem());
1671             HashMap chains = (HashMap)
1672                              corefChains.get(corefAnnotationSetNodesMap.get(
1673                 annotSets.getSelectedItem()));
1674             if (chainNode == null) {
1675               try {
1676                 JOptionPane.showMessageDialog(MainFrame.getInstance(),
1677                                               "Incorrect Chain Title",
1678                                               "New Chain - Error",
1679                                               JOptionPane.ERROR_MESSAGE);
1680               }
1681               catch (Exception e) {
1682                 e.printStackTrace();
1683               }
1684               return;
1685             }
1686             popupWindow.setVisible(false);
1687             ArrayList ids = (ArrayListchains.get(chainNode);
1688 
1689             Map matchesMap = null;
1690             Object matchesMapObject = document.getFeatures().get(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME);
1691             if(matchesMapObject instanceof Map) {
1692               matchesMap = (MapmatchesMapObject;
1693             }
1694 
1695             if (matchesMap == null) {
1696               matchesMap = new HashMap();
1697             }
1698             String currentSet = (StringannotSets.getSelectedItem();
1699             currentSet = (currentSet.equals(DEFAULT_ANNOTSET_NAME)) null :
1700                          currentSet;
1701             java.util.List matches = (java.util.ListmatchesMap.get(currentSet);
1702             if (matches == null)
1703               matches = new ArrayList();
1704             int index = matches.indexOf(ids);
1705             if (index != -1) {
1706               ArrayList tempIds = (ArrayListmatches.get(index);
1707               tempIds.add(ann.getId());
1708               matches.set(index, tempIds);
1709               matchesMap.put(currentSet, matches);
1710               document.getFeatures().put(ANNIEConstants.
1711                                          DOCUMENT_COREF_FEATURE_NAME,
1712                                          matchesMap);
1713             }
1714             return;
1715           }
1716         }
1717       }
1718     }
1719   }
1720 
1721   /** When user hovers over the chainnodes */
1722   protected class ChainToolTipAction
1723       extends AbstractAction {
1724 
1725     int textLocation;
1726     Point mousePoint;
1727     JPopupMenu popup = new JPopupMenu();
1728 
1729     public ChainToolTipAction() {
1730       popup.setBackground(UIManager.getLookAndFeelDefaults().
1731                           getColor("ToolTip.background"));
1732     }
1733 
1734     public void actionPerformed(ActionEvent ae) {
1735 
1736       int index = -1;
1737       if (highlightedChainAnnotsOffsets != null) {
1738         for (int i = 0; i < highlightedChainAnnotsOffsets.length; i += 2) {
1739           if (textLocation >= highlightedChainAnnotsOffsets[i&&
1740               textLocation <= highlightedChainAnnotsOffsets[i + 1]) {
1741             index = (i == 0? i : i / 2;
1742             break;
1743           }
1744         }
1745       }
1746 
1747       // yes it is put on highlighted so show the annotationType
1748       if (highlightedChainAnnotsOffsets != null &&
1749           index < highlightedChainAnnotsOffsets.length && index >= 0) {
1750 
1751         if (popupWindow != null && popupWindow.isVisible()) {
1752           popupWindow.setVisible(false);
1753         }
1754 
1755         popup.setVisible(false);
1756         popup.removeAll();
1757         final int tempIndex = index;
1758         CorefTreeNode chainHead = findOutTheChainHead( (Annotation)
1759             highlightedChainAnnots.get(index)(StringannotSets.getSelectedItem());
1760         final HashMap tempMap = new HashMap();
1761         popup.setLayout(new FlowLayout(FlowLayout.LEFT));
1762         if (chainHead != null) {
1763           JPanel tempPanel = new JPanel();
1764           tempPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
1765           tempPanel.add(new JLabel(chainHead.toString()));
1766           tempPanel.setBackground(UIManager.getLookAndFeelDefaults().
1767                                   getColor("ToolTip.background"));
1768           final JButton deleteButton = new JButton("Delete");
1769           tempPanel.add(deleteButton);
1770           popup.add(tempPanel);
1771           deleteButton.setActionCommand(chainHead.toString());
1772           tempMap.put(chainHead.toString(), chainHead);
1773           deleteButton.addActionListener(new ActionListener() {
1774             public void actionPerformed(ActionEvent ae) {
1775               try {
1776                 int confirm = JOptionPane.showConfirmDialog(MainFrame.getInstance(),
1777                     "Are you sure?""Removing reference...",
1778                     JOptionPane.YES_NO_OPTION);
1779                 if (confirm == JOptionPane.YES_OPTION) {
1780                   popup.setVisible(false);
1781                   // remove it
1782                   removeChainReference( (AnnotationhighlightedChainAnnots.get(
1783                       tempIndex),
1784                       (CorefTreeNodetempMap.get(deleteButton.getActionCommand()));
1785                 }
1786               }
1787               catch (Exception e1) {
1788                 e1.printStackTrace();
1789               }
1790             }
1791           });
1792         }
1793         //label.setText("Remove \""+getString((Annotation) highlightedChainAnnots.get(index)) + "\" from \""+ findOutTheChainHead((Annotation) highlightedChainAnnots.get(index)).toString()+"\"");
1794         popup.revalidate();
1795         if (popupWindow != null && popupWindow.isVisible()) {
1796           popupWindow.setVisible(false);
1797         }
1798         popup.setVisible(true);
1799         popup.show(textPane, (intmousePoint.getX()(intmousePoint.getY());
1800       }
1801     }
1802 
1803     public void setTextLocation(int textLocation) {
1804       this.textLocation = textLocation;
1805     }
1806 
1807     public void setMousePointer(Point point) {
1808       this.mousePoint = point;
1809     }
1810 
1811   }
1812 
1813   // Class that represents each individual tree node in the corefTree
1814   protected class CorefTreeNode
1815       extends DefaultMutableTreeNode {
1816     public final static int ROOT_NODE = 0;
1817     public final static int ANNOTSET_NODE = 1;
1818     public final static int CHAIN_NODE = 2;
1819 
1820     private int type;
1821 
1822     public CorefTreeNode(Object value, boolean allowsChildren, int type) {
1823       super(value, allowsChildren);
1824       this.type = type;
1825     }
1826 
1827     public int getType() {
1828       return this.type;
1829     }
1830 
1831   }
1832 
1833   /**
1834    * Action for mouseClick on the Tree
1835    */
1836   protected class CorefTreeMouseListener
1837       extends MouseAdapter {
1838 
1839     public void mouseClicked(MouseEvent me) { }
1840     public void mouseReleased(MouseEvent me) { }
1841 
1842     public void mousePressed(MouseEvent me) {
1843       if (popupWindow != null && popupWindow.isVisible()) {
1844         popupWindow.setVisible(false);
1845       }
1846       textPane.removeAll();
1847       // ok now find out the currently selected node
1848       int x = me.getX();
1849       int y = me.getY();
1850       int row = corefTree.getRowForLocation(x, y);
1851       TreePath path = corefTree.getPathForRow(row);
1852 
1853       if (path != null) {
1854         final CorefTreeNode node = (CorefTreeNodepath.
1855                                    getLastPathComponent();
1856 
1857         // if it only chainNode
1858         if (node.getType() != CorefTreeNode.CHAIN_NODE) {
1859           return;
1860         }
1861 
1862         // see if user clicked the right click
1863         if (SwingUtilities.isRightMouseButton(me)) {
1864           // it is right click
1865           // we need to show the popup window
1866           final JPopupMenu popup = new JPopupMenu();
1867           JButton delete = new JButton("Delete");
1868           delete.setToolTipText("Delete Chain");
1869           ToolTipManager.sharedInstance().registerComponent(delete);
1870           JButton cancel = new JButton("Close");
1871           cancel.setToolTipText("Closes this popup");
1872           JButton changeColor = new JButton("Change Color");
1873           changeColor.setToolTipText("Changes Color");
1874           ToolTipManager.sharedInstance().registerComponent(cancel);
1875           ToolTipManager.sharedInstance().registerComponent(changeColor);
1876           JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
1877           panel.setOpaque(false);
1878           panel.add(changeColor);
1879           panel.add(delete);
1880           panel.add(cancel);
1881           popup.setLayout(new BorderLayout());
1882           popup.setOpaque(true);
1883           popup.setBackground(UIManager.getLookAndFeelDefaults().
1884                               getColor("ToolTip.background"));
1885           popup.add(new JLabel("Chain \"" + node.toString() "\""),
1886                     BorderLayout.NORTH);
1887           popup.add(panel, BorderLayout.SOUTH);
1888 
1889           changeColor.addActionListener(new ActionListener() {
1890             public void actionPerformed(ActionEvent ae) {
1891               String currentAnnotSet = (StringannotSets.getSelectedItem();
1892               currentColors = (HashMapcolorChainsMap.get(currentAnnotSet);
1893               Color colour = (ColorcurrentColors.get(node.toString());
1894               Color col = JColorChooser.showDialog(getGUI(),
1895                   "Select colour for \"" + node.toString() "\"",
1896                   colour);
1897               if (col != null) {
1898                 Color colAlpha = new Color(col.getRed(), col.getGreen(),
1899                                            col.getBlue()128);
1900 
1901                 // make change in the datastructures
1902                 currentColors.put(node.toString(),colAlpha);
1903                 colorChainsMap.put(currentAnnotSet, currentColors);
1904                 // and redraw the tree
1905                 corefTree.repaint();
1906 
1907                 // remove all highlights
1908                 ArrayList allHighlights = new ArrayList();
1909                 if(typeSpecificHighlightedTags != null)
1910                   allHighlights.addAll(typeSpecificHighlightedTags);
1911                 if(highlightedTags != null) {
1912                   Iterator iter = highlightedTags.values().iterator();
1913                   while(iter.hasNext()) {
1914                     ArrayList highlights = (ArrayListiter.next();
1915                     allHighlights.addAll(highlights);
1916                   }
1917                 }
1918                 for (int i = 0; i < allHighlights.size(); i++) {
1919                   highlighter.removeHighlight(allHighlights.get(i));
1920                 }
1921 
1922                 //highlighter.removeAllHighlights();
1923                 highlightedTags = null;
1924                 highlightAnnotations();
1925                 typeSpecificHighlightedTags = null;
1926                 showTypeWiseAnnotations();
1927               }
1928               popup.setVisible(false);
1929             }
1930           });
1931 
1932           delete.addActionListener(new ActionListener() {
1933             public void actionPerformed(ActionEvent ae) {
1934               // get the ids of current chainNode
1935               HashMap chains = (HashMap)
1936                                corefChains.get(corefAnnotationSetNodesMap.get(
1937                   annotSets.getSelectedItem()));
1938               ArrayList ids = (ArrayListchains.get(node);
1939 
1940               String currentSet = (StringannotSets.getSelectedItem();
1941               currentSet = (currentSet.equals(DEFAULT_ANNOTSET_NAME)) null : currentSet;
1942 
1943               // now search this in the document feature map
1944               Map matchesMap = null;
1945               java.util.List matches = null;
1946 
1947               Object matchesMapObject = document.getFeatures().get(ANNIEConstants.DOCUMENT_COREF_FEATURE_NAME);
1948               if(matchesMapObject instanceof Map) {
1949                 matchesMap = (MapmatchesMapObject;
1950                 matches = (java.util.ListmatchesMap.get(currentSet);
1951               }
1952 
1953               if(matchesMap == null) {
1954                 matchesMap = new HashMap();
1955               }
1956 
1957               if (matches == null)
1958                 matches = new ArrayList();
1959 
1960               int index = matches.indexOf(ids);
1961               if (index != -1) {
1962                 // yes found
1963                 matches.remove(index);
1964                 matchesMap.put(currentSet, matches);
1965                 document.getFeatures().put(ANNIEConstants.
1966                                            DOCUMENT_COREF_FEATURE_NAME,
1967                                            matchesMap);
1968               }
1969               popup.setVisible(false);
1970             }
1971           });
1972 
1973           cancel.addActionListener(new ActionListener() {
1974             public void actionPerformed(ActionEvent ae) {
1975               popup.setVisible(false);
1976             }
1977           });
1978           popup.setVisible(true);
1979           popup.show(corefTree, x, y);
1980           return;
1981         }
1982 
1983         boolean isSelected = ! ( (BooleancurrentSelections.get(node.toString())).
1984                              booleanValue();
1985         currentSelections.put(node.toString()new Boolean(isSelected));
1986 
1987         // so now we need to highlight all the stuff
1988         highlightAnnotations();
1989         corefTree.repaint();
1990         corefTree.updateUI();
1991         corefTree.repaint();
1992         corefTree.updateUI();
1993 
1994       }
1995     }
1996   }
1997 
1998   /**
1999    * Cell renderer to add the checkbox in the tree
2000    */
2001   protected class CorefTreeCellRenderer
2002       extends JPanel
2003       implements TreeCellRenderer {
2004 
2005     private JCheckBox check;
2006     private JLabel label;
2007 
2008     /**
2009      * Constructor.
2010      */
2011     public CorefTreeCellRenderer() {
2012       setOpaque(true);
2013       check = new JCheckBox();
2014       check.setBackground(Color.white);
2015       label = new JLabel();
2016       setLayout(new BorderLayout(510));
2017       add(check, BorderLayout.WEST);
2018       add(label, BorderLayout.CENTER);
2019     }
2020 
2021     /**
2022      * Renderer class
2023      */
2024     public Component getTreeCellRendererComponent(JTree tree, Object value,
2025                                                   boolean isSelected,
2026                                                   boolean expanded,
2027                                                   boolean leaf, int row,
2028                                                   boolean hasFocus) {
2029 
2030       CorefTreeNode userObject = (CorefTreeNodevalue;
2031       label.setText(userObject.toString());
2032       this.setSize(label.getWidth(),
2033                    label.getFontMetrics(label.getFont()).getHeight() 2);
2034       tree.expandRow(row);
2035       if (userObject.getType() == CorefTreeNode.ROOT_NODE || userObject.getType() ==
2036           CorefTreeNode.ANNOTSET_NODE) {
2037         this.setBackground(Color.white);
2038         this.check.setVisible(false);
2039         return this;
2040       }
2041       else {
2042         this.setBackground( (ColorcurrentColors.get(userObject.toString()));
2043         check.setVisible(true);
2044         check.setBackground(Color.white);
2045       }
2046 
2047       // if node should be selected
2048       boolean selected = ( (BooleancurrentSelections.get(userObject.toString())).
2049                          booleanValue();
2050       check.setSelected(selected);
2051       return this;
2052     }
2053   }
2054 }