1   /*  AnnotDiffDialog.java
2    *  Copyright (c) 1998-2004, The University of Sheffield.
3    *
4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
5    *  software, licenced under the GNU Library General Public License,
6    *  Version 2, June 1991 (in the distribution as file licence.html,
7    *  and also available at http://gate.ac.uk/gate/licence.html).
8    *
9    *  Cristian URSU, 7/03/2001
10   *
11   *  $Id: AnnotDiffDialog.java,v 1.25 2004/08/06 16:08:25 valyt Exp $
12   *
13   */
14  package gate.gui;
15  
16  import java.awt.*;
17  import java.awt.event.*;
18  import java.util.*;
19  
20  import javax.swing.*;
21  
22  import gate.*;
23  import gate.annotation.AnnotationDiff;
24  import gate.creole.*;
25  
26  /** This class wraps the {@link gate.annotation.AnnotationDiff} one. It adds the
27    * the GUI functionality needed to set up params for AnnotationDiff and also
28    * adds the AnnotationDiff as a tool in GATE.
29    */
30  class AnnotDiffDialog extends JFrame {
31    // Local data needed in initLocalData() method
32  
33    /** A map from documentName 2 GATE document It is used to display names in
34      * combo boxes
35      */
36    Map  documentsMap = null;
37    /** A map from AnnotationSetNames 2 AnnotationSets, used to display AnnotSets
38      * in combo boxes
39      */
40    Map keyAnnotationSetMap = null;
41    /** A map from AnnotationSetNames 2 AnnotationSets, used to display AnnotSets
42      * in combo boxes
43      */
44    Map responseAnnotationSetMap = null;
45    /** A map from Annotation types 2 AnnotationSchema,
46      * used to display annotations in combo boxes
47      */
48    Map  typesMap = null;
49    /** A set containing annot types for calculating falsePoz measure*/
50    Set  falsePozTypes = null;
51    /** AnnotDiff's tool parent frame*/
52    MainFrame mainFrame = null;
53    /** A pointer to this object used in some internal classes*/
54    AnnotDiffDialog thisAnnotDiffDialog = null;
55  
56    // GUI components used in initGuiComponents()
57    /** Renders key documents*/
58    JComboBox keyDocComboBox = null;
59    /** Renders response documents*/
60    JComboBox responseDocComboBox = null;
61    /** Renders annot types which come from intersecting keyAnnotSet with
62      * responseAnnotSet
63      */
64    JComboBox typesComboBox = null;
65    /** Renders annot types used in calculating falsPoz measure*/
66    JComboBox falsePozTypeComboBox = null;
67    /** Renders the annotation sets that come from the response document and
68      * used in calculating falsePoz measure
69      */
70    JComboBox responseDocAnnotSetFalsePozComboBox = null;
71    /** Renders the annotation sets that come from the key document*/
72    JComboBox keyDocAnnotSetComboBox = null;
73    /** Renders the annotation sets that come from the response document*/
74    JComboBox responseDocAnnotSetComboBox = null;
75    /** Renders the text label for keyDocAnnotSetComboBox*/
76    JLabel keyLabel = null;
77    /** Renders the text label for responseDocAnnotSetComboBox*/
78    JLabel responseLabel = null;
79    /** Renders the text label for typesComboBox*/
80    JLabel typesLabel = null;
81    /** Renders the text label for falsePozTypeComboBox*/
82    JLabel falsePozLabel = null;
83    /** Renders the text label for keyDocComboBox*/
84    JLabel keyDocAnnotSetLabel = null;
85    /** Renders the text label for responseDocComboBox*/
86    JLabel responseDocAnnotSetLabel = null;
87    /** Renders the text label for responseDocComboBox used in calc falsePoz.*/
88    JLabel responseDocAnnotSetFalsePozLabel = null;
89    /** Renders the label for weightTextField*/
90    JLabel weightLabel = null;
91    /** Renders the value of weight used in calculating F measure*/
92    JTextField weightTextField = null;
93    /** Renders the button which triggers the diff process*/
94    JButton evalButton = null;
95    /** A reference to annotDiff object that does the diff*/
96    AnnotationDiff annotDiff = null;
97    /** A split between configuration pannel and AnnotDifff*/
98    JSplitPane jSplit = null;
99    /** A Radio button for selecting certian features that would be used in diff*/
100   JRadioButton someFeaturesRadio = null;
101   /** A Radio button for selecting no features that would be used in diff*/
102   JRadioButton noFeaturesRadio = null;
103   /** A Radio button for selecting all features that would be used in diff*/
104   JRadioButton allFeaturesRadio = null;
105   /** A group buttons for the 3 Radio buttons above*/
106   ButtonGroup groupRadios = null;
107   /** A label for Radio Buttons selection*/
108   JLabel selectFeaturesLabel = null;
109   /** A selection dialog used in case that the user selects some radio button*/
110   CollectionSelectionDialog featureSelectionDialog = null;
111   /** Constructs an annotDiffDialog object having as parent aMainFrame
112     * @param aMainFrame the parent frame for this AnnotDiffDialog. If can be
113     * <b>null</b>, meaning no parent.
114     */
115   public AnnotDiffDialog(MainFrame aMainFrame){
116     mainFrame = aMainFrame;
117     thisAnnotDiffDialog = this;
118     initLocalData();
119     initGuiComponents();
120     initListeners();
121   }//AnnotDiffDialog
122 
123   /** This method is called when adding or removing a document*/
124   public void updateData(){
125     documentsMap = null;
126     typesMap = null;
127     falsePozTypes = null;
128     this.removeAll();
129 
130     SwingUtilities.invokeLater(new Runnable(){
131       public void run(){
132         initLocalData();
133         initGuiComponents();
134         initListeners();
135       }
136     });
137   }//updateData()
138 
139   /** Initialises the data needed to set up {@link gate.annotation.AnnotationDiff}
140     * GUI components will be build using this data.
141     */
142   public void initLocalData(){
143     annotDiff = new AnnotationDiff();
144     // Get all available documents and construct the documentsMap
145     // (docName, gate.Document) pairs
146     documentsMap = new HashMap();
147 
148     CreoleRegister registry =  Gate.getCreoleRegister();
149     ResourceData resourceData =
150                         (ResourceData)registry.get("gate.corpora.DocumentImpl");
151     if(resourceData != null && !resourceData.getInstantiations().isEmpty()){
152       java.util.List instantiations = resourceData.getInstantiations();
153       Iterator iter = instantiations.iterator();
154       while (iter.hasNext()){
155         Resource resource = (Resource) iter.next();
156         String docName = resource.getName ();
157         gate.Document doc = (Document) resource;
158         // add it to the Map
159         documentsMap.put(docName,doc);
160       }// while
161     }else documentsMap.put("No docs found",null);
162 
163     keyAnnotationSetMap = new TreeMap();
164     responseAnnotationSetMap = new TreeMap();
165 
166     typesMap = new TreeMap();
167     // init types map with Type,AnnotationSchema pairs
168     typesMap.put("No annot.",null);
169 
170     // init falsePozTypes
171     falsePozTypes = new TreeSet();
172     falsePozTypes.add("No annot.");
173   }// initLocalData
174 
175   /**
176     * This method initializes the GUI components. Data is loaded from localData
177     * fields.
178     */
179   public void initGuiComponents(){
180 
181     //Initialise GUI components
182     //this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
183     this.getContentPane().setLayout(new BorderLayout());
184     // init keyDocComboBox
185     Set comboCont = new TreeSet(documentsMap.keySet());
186     keyDocComboBox = new JComboBox(comboCont.toArray());
187     keyDocComboBox.setSelectedIndex(0);
188     keyDocComboBox.setEditable(false);
189     keyDocComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
190     Dimension dim = new Dimension(150,keyDocComboBox.getPreferredSize().height);
191     keyDocComboBox.setPreferredSize(dim);
192     keyDocComboBox.setMaximumSize(dim);
193     keyDocComboBox.setMinimumSize(dim);
194     keyDocComboBox.setRenderer(new MyCellRenderer(Color.green, Color.black));
195     // init its label
196     keyLabel = new JLabel("Select the KEY doc");
197     keyLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
198     keyLabel.setOpaque(true);
199     keyLabel.setFont(keyLabel.getFont().deriveFont(Font.BOLD));
200     keyLabel.setForeground(Color.black);
201     keyLabel.setBackground(Color.green);
202 
203     // init keyDocAnnotSetComboBox
204     Set comboAsCont = new TreeSet(keyAnnotationSetMap.keySet());
205     keyDocAnnotSetComboBox = new JComboBox(comboAsCont.toArray());
206     keyDocAnnotSetComboBox.setEditable(false);
207     keyDocAnnotSetComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
208     // init its label
209     keyDocAnnotSetLabel = new JLabel("Select the KEY annotation set");
210     keyDocAnnotSetLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
211     keyDocAnnotSetLabel.setOpaque(true);
212     keyDocAnnotSetLabel.setFont(
213                   keyDocAnnotSetLabel.getFont().deriveFont(Font.BOLD));
214     keyDocAnnotSetLabel.setForeground(Color.black);
215     keyDocAnnotSetLabel.setBackground(Color.green);
216 
217     // init responseDocComboBox
218     responseDocComboBox = new JComboBox(comboCont.toArray());
219     responseDocComboBox.setSelectedIndex(0);
220     responseDocComboBox.setEditable(false);
221     responseDocComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
222     responseDocComboBox.setPreferredSize(dim);
223     responseDocComboBox.setMaximumSize(dim);
224     responseDocComboBox.setMinimumSize(dim);
225     responseDocComboBox.setRenderer(new MyCellRenderer(Color.red, Color.black));
226     // init its label
227     responseLabel = new JLabel("Select the RESPONSE doc");
228     responseLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
229     responseLabel.setOpaque(true);
230     responseLabel.setFont(responseLabel.getFont().deriveFont(Font.BOLD));
231     responseLabel.setBackground(Color.red);
232     responseLabel.setForeground(Color.black);
233 
234     // init responseDocAnnotSetComboBox
235     comboAsCont = new TreeSet(responseAnnotationSetMap.keySet());
236     responseDocAnnotSetComboBox = new JComboBox(comboAsCont.toArray());
237     responseDocAnnotSetComboBox.setEditable(false);
238     responseDocAnnotSetComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
239     // init its label
240     responseDocAnnotSetLabel = new JLabel("Select the RESPONSE annot set");
241     responseDocAnnotSetLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
242     responseDocAnnotSetLabel.setOpaque(true);
243     responseDocAnnotSetLabel.setFont(
244                   responseDocAnnotSetLabel.getFont().deriveFont(Font.BOLD));
245     responseDocAnnotSetLabel.setForeground(Color.black);
246     responseDocAnnotSetLabel.setBackground(Color.red);
247 
248     // init responseDocAnnotSetFalsePozComboBox
249     // This combo is used in calculating False Poz
250     comboAsCont = new TreeSet(responseAnnotationSetMap.keySet());
251     responseDocAnnotSetFalsePozComboBox = new JComboBox(comboAsCont.toArray());
252     responseDocAnnotSetFalsePozComboBox.setEditable(false);
253     responseDocAnnotSetFalsePozComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
254     // init its label
255     responseDocAnnotSetFalsePozLabel = new JLabel("Select the RESPONSE annot set");
256     responseDocAnnotSetFalsePozLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
257     responseDocAnnotSetFalsePozLabel.setOpaque(true);
258     responseDocAnnotSetFalsePozLabel.setFont(
259               responseDocAnnotSetFalsePozLabel.getFont().deriveFont(Font.BOLD));
260     responseDocAnnotSetFalsePozLabel.setForeground(Color.black);
261     responseDocAnnotSetFalsePozLabel.setBackground(Color.red);
262 
263 
264     // init typesComboBox
265     Vector typesCont = new Vector(typesMap.keySet());
266     Collections.sort(typesCont);
267     typesComboBox = new JComboBox(typesCont);
268     dim = new Dimension(Integer.MAX_VALUE, typesComboBox.getPreferredSize().height);
269     typesComboBox.setMaximumSize(dim);
270 
271 
272     typesComboBox.setEditable(false);
273     typesComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
274     // init its label
275     typesLabel = new JLabel("Select annot. type");
276     typesLabel.setFont(typesLabel.getFont().deriveFont(Font.BOLD));
277     typesLabel.setOpaque(true);
278     typesLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
279 
280     // init falsePozTypeComboBox
281     falsePozTypeComboBox = new JComboBox(falsePozTypes.toArray());
282     falsePozTypeComboBox.setEditable(false);
283     falsePozTypeComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
284     // init its label
285     falsePozLabel = new JLabel("Select annot. type for FalsePoz");
286     falsePozLabel.setFont(falsePozLabel.getFont().deriveFont(Font.BOLD));
287     falsePozLabel.setOpaque(true);
288     falsePozLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
289 
290     // init weightTextField
291     weightTextField = new JTextField(
292                               (new Double(AnnotationDiff.weight)).toString());
293     weightTextField.setAlignmentX(Component.LEFT_ALIGNMENT);
294     // init its label
295     weightLabel = new JLabel("Weight for F-Measure");
296     weightLabel.setFont(falsePozLabel.getFont().deriveFont(Font.BOLD));
297     weightLabel.setOpaque(true);
298     weightLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
299 
300     // Set initial dimmension for weightTextField
301     Dimension d = new Dimension(weightLabel.getPreferredSize().width,
302                                     weightTextField.getPreferredSize().height);
303     weightTextField.setMinimumSize(d);
304     weightTextField.setMaximumSize(d);
305     weightTextField.setPreferredSize(d);
306 
307     // evaluate button
308     evalButton = new JButton("Evaluate");
309     evalButton.setFont(evalButton.getFont().deriveFont(Font.BOLD));
310 
311     // Some features radio Button
312     someFeaturesRadio = new JRadioButton("Some");
313     someFeaturesRadio.setToolTipText("Select some features from the key"+
314       " annotation set, that will be taken into consideration"+
315       " in the diff process.");
316     // No features RB
317     noFeaturesRadio = new JRadioButton("None");
318     noFeaturesRadio.setToolTipText("No features from the key"+
319       " annotation set will be taken into consideration"+
320       " in the diff process.");
321     // All features RB
322     allFeaturesRadio = new JRadioButton("All");
323     allFeaturesRadio.setSelected(true);
324     allFeaturesRadio.setToolTipText("All features from the key"+
325       " annotation set will be taken into consideration"+
326       " in the diff process.");
327     // Add radio buttons to the group
328     groupRadios = new ButtonGroup();
329     groupRadios.add(allFeaturesRadio);
330     groupRadios.add(someFeaturesRadio);
331     groupRadios.add(noFeaturesRadio);
332     // The label for the Features radio buttons group
333     selectFeaturesLabel = new JLabel("Features");
334     selectFeaturesLabel.setFont(falsePozLabel.getFont().deriveFont(Font.BOLD));
335     selectFeaturesLabel.setOpaque(true);
336     selectFeaturesLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
337     // ***************************************************************
338     // Put all those components at their place
339     // ***************************************************************
340     Box northBox = new Box(BoxLayout.X_AXIS);
341     // Arange Key Document components
342     Box currentBox = new Box(BoxLayout.Y_AXIS);
343     currentBox.add(keyLabel);
344     currentBox.add(keyDocComboBox);
345     currentBox.add(Box.createVerticalStrut(10));
346     currentBox.add(responseLabel);
347     currentBox.add(responseDocComboBox);
348     northBox.add(currentBox);
349 
350     northBox.add(Box.createRigidArea(new Dimension(10,0)));
351 
352     // Arange annotation set components
353     currentBox = new Box(BoxLayout.Y_AXIS);
354     currentBox.add(keyDocAnnotSetLabel);
355     currentBox.add(keyDocAnnotSetComboBox);
356     currentBox.add(Box.createVerticalStrut(10));
357     currentBox.add(responseDocAnnotSetLabel);
358     currentBox.add(responseDocAnnotSetComboBox);
359     northBox.add(currentBox);
360 
361     northBox.add(Box.createRigidArea(new Dimension(10,0)));
362 
363     // Arange annotation types components
364     currentBox = new Box(BoxLayout.Y_AXIS);
365     currentBox.add(typesLabel);
366     currentBox.add(typesComboBox);
367     currentBox.add(Box.createVerticalGlue());
368     northBox.add(currentBox);
369 
370     northBox.add(Box.createRigidArea(new Dimension(10,0)));
371 
372     // Arrange the radio buttons
373     currentBox = new Box(BoxLayout.Y_AXIS);
374     currentBox.add(selectFeaturesLabel);
375     currentBox.add(allFeaturesRadio);
376     currentBox.add(someFeaturesRadio);
377     currentBox.add(noFeaturesRadio);
378     northBox.add(currentBox);
379 
380     northBox.add(Box.createRigidArea(new Dimension(10,0)));
381 
382     // Arange F-Measure weight components
383     currentBox = new Box(BoxLayout.Y_AXIS);
384     currentBox.add(weightLabel);
385     currentBox.add(weightTextField);
386     northBox.add(currentBox);
387 
388     northBox.add(Box.createRigidArea(new Dimension(10,0)));
389 
390     // Arange false poz components
391     currentBox = new Box(BoxLayout.Y_AXIS);
392     currentBox.add(falsePozLabel);
393     currentBox.add(falsePozTypeComboBox);
394     currentBox.add(Box.createVerticalStrut(10));
395     currentBox.add(responseDocAnnotSetFalsePozLabel);
396     currentBox.add(responseDocAnnotSetFalsePozComboBox);
397     northBox.add(currentBox);
398 
399     northBox.add(Box.createRigidArea(new Dimension(10,0)));
400     northBox.add(evalButton);
401 
402     initKeyAnnotSetNames();
403     initResponseAnnotSetNames();
404     initAnnotTypes();
405     initAnnotTypesFalsePoz();
406 
407     this.getContentPane().setLayout(new BoxLayout(this.getContentPane(),
408                                                             BoxLayout.Y_AXIS));
409     Dimension maxDimm = Toolkit.getDefaultToolkit().getScreenSize();
410     Dimension newDim = new Dimension(maxDimm.width/3, maxDimm.height/3);
411     JScrollPane upperScrolPane = new JScrollPane(northBox);
412     upperScrolPane.getViewport().
413                     putClientProperty("EnableWindowBlit", new Boolean(true));
414     JScrollPane lowerScrolPane = new JScrollPane(annotDiff);
415     lowerScrolPane.getViewport().
416                     putClientProperty("EnableWindowBlit", new Boolean(true));
417     lowerScrolPane.setMaximumSize(newDim);
418     lowerScrolPane.setMinimumSize(newDim);
419     lowerScrolPane.setPreferredSize(newDim);
420 
421     jSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
422                                upperScrolPane,
423                                lowerScrolPane);
424     jSplit.setOneTouchExpandable(true);
425     jSplit.setOpaque(true);
426     jSplit.setAlignmentY(Component.TOP_ALIGNMENT);
427     this.getContentPane().add(jSplit);
428     this.pack();
429     ////////////////////////////////
430     // Center it on screen
431     ///////////////////////////////
432     Dimension ownerSize;
433     Point ownerLocation;
434     if(getOwner() == null){
435       ownerSize = Toolkit.getDefaultToolkit().getScreenSize();
436       ownerLocation = new Point(0, 0);
437     }else{
438       ownerSize = getOwner().getSize();
439       ownerLocation = getOwner().getLocation();
440       if(ownerSize.height == 0 ||
441          ownerSize.width == 0 ||
442          !getOwner().isVisible()){
443         ownerSize = Toolkit.getDefaultToolkit().getScreenSize();
444         ownerLocation = new Point(0, 0);
445       }
446     }
447     //Center the window
448     Dimension frameSize = getSize();
449     if (frameSize.height > ownerSize.height)
450       frameSize.height = ownerSize.height;
451     if (frameSize.width > ownerSize.width)
452       frameSize.width = ownerSize.width;
453     setLocation(ownerLocation.x + (ownerSize.width - frameSize.width) / 2,
454                 ownerLocation.y + (ownerSize.height - frameSize.height) / 2);
455 
456   }//initGuiComponents
457 
458   /** This method is called when the user want to close the tool. See
459     * initListeners() method for more details
460     */
461   void this_windowClosing(WindowEvent e){
462     this.setVisible(false);
463   }//this_windowClosing();
464 
465   /** This method starts AnnotationDiff tool in a separate thread.*/
466   private void doDiff(){
467     try{
468       Double d = new Double(thisAnnotDiffDialog.getCurrentWeight());
469       AnnotationDiff.weight = d.doubleValue();
470     }catch (NumberFormatException e){
471         JOptionPane.showMessageDialog(thisAnnotDiffDialog,
472                      "The weight for F-Measure should be a double !",
473                      "Annotation Diff initialization error !",
474                      JOptionPane.ERROR_MESSAGE);
475         return;
476     }// End try
477     Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
478                                new DiffRunner(),
479                                "AnnotDiffDialog1");
480     thread.setPriority(Thread.MIN_PRIORITY);
481     thread.start();
482   }//doDiff();
483 
484   /**This one initializes the listeners fot the GUI components */
485   public void initListeners(){
486 
487     this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
488     this.addWindowListener(new java.awt.event.WindowAdapter() {
489       public void windowClosing(WindowEvent e) {
490         this_windowClosing(e);
491       }// windowClosing();
492     });// addWindowListener();
493 
494     evalButton.addActionListener(new java.awt.event.ActionListener() {
495       public void actionPerformed(ActionEvent e) {
496          thisAnnotDiffDialog.doDiff();
497       }// actionPerformed();
498     });//addActionListener();
499 
500     keyDocComboBox.addActionListener(new ActionListener() {
501       public void actionPerformed(ActionEvent e) {
502         initKeyAnnotSetNames();
503         initAnnotTypes();
504       }// actionPerformed();
505     });//addActionListener();
506 
507     responseDocComboBox.addActionListener(new ActionListener() {
508       public void actionPerformed(ActionEvent e) {
509         initResponseAnnotSetNames();
510         initAnnotTypes();
511       }// actionPerformed();
512     });//addActionListener();
513 
514     keyDocAnnotSetComboBox.addActionListener(new ActionListener() {
515       public void actionPerformed(ActionEvent e) {
516         initAnnotTypes();
517       }// actionPerformed();
518     });//addActionListener();
519 
520     responseDocAnnotSetComboBox.addActionListener(new ActionListener() {
521       public void actionPerformed(ActionEvent e) {
522         initAnnotTypes();
523       }// actionPerformed();
524     });//addActionListener();
525 
526     responseDocAnnotSetFalsePozComboBox.addActionListener(new ActionListener() {
527       public void actionPerformed(ActionEvent e) {
528         initAnnotTypesFalsePoz();
529       }// actionPerformed();
530     });//addActionListener();
531 
532     typesComboBox.addActionListener(new ActionListener() {
533       public void actionPerformed(ActionEvent e){
534         if (featureSelectionDialog != null) featureSelectionDialog = null;
535       }// actionPerformed();
536     });//addActionListener();
537 
538     someFeaturesRadio.addActionListener(new ActionListener() {
539       public void actionPerformed(ActionEvent e){
540         collectSomeFeatures();
541       }// actionPerformed();
542     });//addActionListener();
543 
544   }//initListeners();
545 
546   /** Activates the CollectionSelectionDialog in order to colect those feature
547     * from key that will take part in the diff process
548     */
549   private void collectSomeFeatures(){
550     if (featureSelectionDialog == null){
551       featureSelectionDialog = new CollectionSelectionDialog(
552                                                 thisAnnotDiffDialog,true);
553     }else{
554       featureSelectionDialog.setVisible(true);
555       return;
556     }// End if
557     // For the current annotation type take all the features that appear in the
558     // key set and initialize the featureSelectionDialog
559     gate.Document keyDocument = null;
560     keyDocument = (gate.Document) documentsMap.get(
561                                  (String)keyDocComboBox.getSelectedItem());
562     if (keyDocument == null){
563       JOptionPane.showMessageDialog(this,
564                                     "Select a key document first !",
565                                     "GATE", JOptionPane.ERROR_MESSAGE);
566       featureSelectionDialog = null;
567       return;
568     }//End if
569 
570     AnnotationSet keySet = null;
571     if (keyDocAnnotSetComboBox.getSelectedItem()== null ||
572         keyAnnotationSetMap.get(keyDocAnnotSetComboBox.getSelectedItem())==null)
573       // First add to the keySet all annotations from default set
574       keySet = keyDocument.getAnnotations();
575     else{
576       // Get all types of annotation from the selected keyAnnotationSet
577       AnnotationSet as = (AnnotationSet) keyAnnotationSetMap.get(
578                                   keyDocAnnotSetComboBox.getSelectedItem());
579       keySet = as;
580     }// End if
581     if (keySet == null){
582       JOptionPane.showMessageDialog(this,
583                                     "Select some annotation sets first !",
584                                     "GATE", JOptionPane.ERROR_MESSAGE);
585       featureSelectionDialog = null;
586       return;
587     }// End if
588     AnnotationSchema annotSchema = (AnnotationSchema)
589                                 typesMap.get(typesComboBox.getSelectedItem());
590     if (annotSchema == null){
591       JOptionPane.showMessageDialog(this,
592                                     "Select some annotation types first !",
593                                     "GATE", JOptionPane.ERROR_MESSAGE);
594       featureSelectionDialog = null;
595       return;
596     }// End if
597     AnnotationSet selectedTypeSet = keySet.get(annotSchema.getAnnotationName());
598     Set featureNamesSet = new TreeSet();
599     // Iterate this set and get all feature keys.
600     Iterator selectedTypeIterator = selectedTypeSet.iterator();
601     while(selectedTypeIterator.hasNext()){
602       Annotation a = (Annotation) selectedTypeIterator.next();
603       if (a.getFeatures() != null)
604         featureNamesSet.addAll(a.getFeatures().keySet());
605     }// End while
606     featureSelectionDialog.show("Select features for annotation type \"" +
607         annotSchema.getAnnotationName()+ "\" that would be used in diff proces",
608         featureNamesSet);
609   }//collectSomeFeatures();
610 
611   /** Initializes the annotations for false Poz masure*/
612   private void initAnnotTypesFalsePoz(){
613     gate.Document responseDocument = null;
614     responseDocument = (gate.Document) documentsMap.get(
615                                  (String)responseDocComboBox.getSelectedItem());
616     falsePozTypes.clear();
617     if (responseDocument == null){
618       // init falsePozTypes
619       falsePozTypes.add("No annot.");
620       DefaultComboBoxModel cbm = new DefaultComboBoxModel(falsePozTypes.toArray());
621       falsePozTypeComboBox.setModel(cbm);
622       return;
623     }//End if
624 
625     // Fill the responseSet
626     Set responseSet = null;
627     if (responseDocAnnotSetFalsePozComboBox.getSelectedItem() == null ||
628         responseAnnotationSetMap.get(
629                    responseDocAnnotSetFalsePozComboBox.getSelectedItem())==null)
630         responseSet = new HashSet(
631                               responseDocument.getAnnotations().getAllTypes());
632     else{
633       // Get all types of annotation from the selected responseAnnotationSet
634       AnnotationSet as = (AnnotationSet) responseAnnotationSetMap.get(
635                          responseDocAnnotSetFalsePozComboBox.getSelectedItem());
636       responseSet = new HashSet(as.getAllTypes());
637     }// End if
638 
639     // Init falsePozTypes
640     falsePozTypes.addAll(responseSet);
641     if (falsePozTypes.isEmpty())
642       falsePozTypes.add("No annot.");
643     DefaultComboBoxModel cbm = new DefaultComboBoxModel(falsePozTypes.toArray());
644     falsePozTypeComboBox.setModel(cbm);
645   }//initAnnotTypesFalsePoz();
646 
647   /** Reads the selected keyDocument + the selected responseDocument and
648     * also reads the selected annotation sets from Key and response and
649     * intersects the annotation types. The result is the typesComboBox which
650     * is filled with the intersected types.
651     */
652   private void initAnnotTypes(){
653     gate.Document keyDocument = null;
654     gate.Document responseDocument = null;
655 
656     keyDocument = (gate.Document) documentsMap.get(
657                                  (String)keyDocComboBox.getSelectedItem());
658     responseDocument = (gate.Document) documentsMap.get(
659                                  (String)responseDocComboBox.getSelectedItem());
660 
661     typesMap.clear();
662 
663     if (keyDocument == null || responseDocument == null){
664       // init types map with Type,AnnotationSchema pairs
665       typesMap.put("No annot.",null);
666       ComboBoxModel cbm = new DefaultComboBoxModel(typesMap.keySet().toArray());
667       typesComboBox.setModel(cbm);
668       return;
669     }//End if
670 
671     // Do intersection for annotation types...
672     // First fill the keySet;
673     Set keySet = null;
674     if (keyDocAnnotSetComboBox.getSelectedItem()== null ||
675         keyAnnotationSetMap.get(keyDocAnnotSetComboBox.getSelectedItem())==null)
676       // First add to the keySet all annotations from default set
677       keySet = new HashSet(keyDocument.getAnnotations().getAllTypes());
678     else{
679       // Get all types of annotation from the selected keyAnnotationSet
680       AnnotationSet as = (AnnotationSet) keyAnnotationSetMap.get(
681                                   keyDocAnnotSetComboBox.getSelectedItem());
682       keySet = new HashSet(as.getAllTypes());
683     }// End if
684 
685     // Do the same thing for the responseSet
686     // Fill the responseSet
687     Set responseSet = null;
688     if (responseDocAnnotSetComboBox.getSelectedItem() == null ||
689         responseAnnotationSetMap.get(
690                           responseDocAnnotSetComboBox.getSelectedItem())==null)
691         responseSet = new HashSet(
692                               responseDocument.getAnnotations().getAllTypes());
693     else{
694       // Get all types of annotation from the selected responseAnnotationSet
695       AnnotationSet as = (AnnotationSet) responseAnnotationSetMap.get(
696                                  responseDocAnnotSetComboBox.getSelectedItem());
697       responseSet = new HashSet(as.getAllTypes());
698     }// End if
699 
700     // DO intersection between keySet & responseSet
701     keySet.retainAll(responseSet);
702     Set intersectSet = keySet;
703 
704     Iterator iter = intersectSet.iterator();
705     while (iter.hasNext()){
706       String annotName = (String) iter.next();
707 
708       AnnotationSchema schema = new AnnotationSchema();
709       schema.setAnnotationName(annotName);
710 
711       typesMap.put(annotName,schema);
712     }// while
713 
714     if (typesMap.isEmpty())
715       typesMap.put("No annot.",null);
716 
717     DefaultComboBoxModel cbm = new DefaultComboBoxModel(
718                                               typesMap.keySet().toArray());
719     typesComboBox.setModel(cbm);
720   }//initAnnotTypes();
721 
722   /** Reads the selected keyDocument + the selected responseDocument and fill
723     * the two combo boxes called keyDocAnnotSetComboBox and
724     * responseDocAnnotSetComboBox.
725     */
726   private void initKeyAnnotSetNames(){
727     gate.Document keyDocument = null;
728     keyDocument = (gate.Document) documentsMap.get(
729                                  (String)keyDocComboBox.getSelectedItem());
730     keyAnnotationSetMap.clear();
731 
732     if (keyDocument != null){
733       Map namedAnnotSets = keyDocument.getNamedAnnotationSets();
734       if (namedAnnotSets != null)
735         keyAnnotationSetMap.putAll(namedAnnotSets);
736       keyAnnotationSetMap.put("Default set",null);
737       DefaultComboBoxModel cbm = new DefaultComboBoxModel(
738                                         keyAnnotationSetMap.keySet().toArray());
739       keyDocAnnotSetComboBox.setModel(cbm);
740     }// End if
741   }//initKeyAnnotSetNames();
742 
743   /** Reads the selected responseDocument and fill
744     * the combo box called responseDocAnnotSetFalsePozComboBox as well as
745     * responseDocAnnotSetComboBox.
746     */
747   private void initResponseAnnotSetNames(){
748     gate.Document responseDocument = null;
749     responseDocument = (gate.Document) documentsMap.get(
750                                  (String)responseDocComboBox.getSelectedItem());
751     responseAnnotationSetMap.clear();
752 
753     if (responseDocument != null){
754       Map namedAnnotSets = responseDocument.getNamedAnnotationSets();
755       if (namedAnnotSets != null)
756         responseAnnotationSetMap.putAll(namedAnnotSets);
757       responseAnnotationSetMap.put("Default set",null);
758       DefaultComboBoxModel cbm = new DefaultComboBoxModel(
759                                   responseAnnotationSetMap.keySet().toArray());
760       responseDocAnnotSetComboBox.setModel(cbm);
761       cbm = new DefaultComboBoxModel(
762                                   responseAnnotationSetMap.keySet().toArray());
763       responseDocAnnotSetFalsePozComboBox.setModel(cbm);
764     }// End if
765   }//initResponseAnnotSetNames();
766 
767   /** It returns the selected KEY gate.Document*/
768   public gate.Document getSelectedKeyDocument(){
769     return (gate.Document) documentsMap.get(
770                                 (String)keyDocComboBox.getSelectedItem());
771   }//getSelectedKeyDocument
772 
773   /** It returns the selected RESPONSE gate.Document*/
774   public gate.Document getSelectedResponseDocument(){
775     return (gate.Document) documentsMap.get(
776                                 (String)responseDocComboBox.getSelectedItem());
777   }//getSelectedResponseDocument
778 
779   /** It returns the selected SCHEMA  */
780   public AnnotationSchema getSelectedSchema(){
781     return (AnnotationSchema) typesMap.get(
782                                 (String)typesComboBox.getSelectedItem());
783   }//getSelectedSchema
784 
785   /** It returns the current weight  */
786   public String getCurrentWeight(){
787     return weightTextField.getText();
788   }//getCurrentWeight
789 
790   /** It returns the selected Annotation to calculate the False Pozitive  */
791   public String getSelectedFalsePozAnnot(){
792     return (String) falsePozTypeComboBox.getSelectedItem();
793   }//getSelectedFalsePozAnnot
794 
795   /** It returns the selected key AnnotationSet name. It returns null for the
796     * default annotation set.
797     */
798   public String getSelectedKeyAnnotationSetName(){
799    String asName = (String) keyDocAnnotSetComboBox.getSelectedItem();
800    if ("Default set".equals(asName)) return null;
801    else return asName;
802   }//getSelectedKeyAnnotationSetName()
803 
804   /** It returns the selected response AnnotationSet name.It returns null for the
805     * default annotation set.
806     */
807   public String getSelectedResponseAnnotationSetName(){
808    String asName = (String) responseDocAnnotSetComboBox.getSelectedItem();
809    if ("Default set".equals(asName)) return null;
810    else return asName;
811   }//getSelectedResponseAnnotationSetName()
812 
813   /** It returns the selected response AnnotationSet name for False Poz.
814     * It returns null for the default annotation set.
815     */
816   public String getSelectedResponseAnnotationSetNameFalsePoz(){
817    String asName = (String) responseDocAnnotSetFalsePozComboBox.getSelectedItem();
818    if ("Default set".equals(asName)) return null;
819    else return asName;
820   }//getSelectedResponseAnnotationSetNameFalsePoz()
821 
822   /**  Inner class that adds a tool tip to the combo boxes with key and response
823     *  documents. The tool tip represents the full path of the documents.
824     */
825   class MyCellRenderer extends JLabel implements ListCellRenderer {
826 
827      Color background = null;
828      Color foreground = null;
829      /** Constructs a renderer*/
830      public MyCellRenderer(Color aBackground, Color aForeground){
831          setOpaque(true);
832          background = aBackground;
833          foreground = aForeground;
834      }// MyCellRenderer();
835 
836      /** This method is overridden in order to implement the needed behaviour*/
837      public Component getListCellRendererComponent(
838                                                    JList list,
839                                                    Object value,
840                                                    int index,
841                                                    boolean isSelected,
842                                                    boolean cellHasFocus){
843          // should be done only once...
844          ToolTipManager.sharedInstance().registerComponent(list);
845          setText(value.toString());
846          setBackground(isSelected ? background : Color.white);
847          setForeground(isSelected ? foreground : Color.black);
848          if (isSelected)
849              list.setToolTipText(value.toString());
850          return this;
851      }// getListCellRendererComponent()
852   }//MyCellRenderer
853 
854   /**Inner class used to run an annot. diff in a new thread*/
855   class DiffRunner implements Runnable{
856     /** Constructor */
857     public DiffRunner(){}// DiffRuner
858     /** This method is overridden in order to implement the needed behaviour*/
859     public void run(){
860       annotDiff.setKeyDocument(thisAnnotDiffDialog.getSelectedKeyDocument());
861       annotDiff.setResponseDocument(
862                           thisAnnotDiffDialog.getSelectedResponseDocument());
863       annotDiff.setAnnotationSchema(thisAnnotDiffDialog.getSelectedSchema());
864       annotDiff.setKeyAnnotationSetName(
865                       thisAnnotDiffDialog.getSelectedKeyAnnotationSetName());
866       annotDiff.setResponseAnnotationSetName(
867                   thisAnnotDiffDialog.getSelectedResponseAnnotationSetName());
868       annotDiff.setResponseAnnotationSetNameFalsePoz(
869             thisAnnotDiffDialog.getSelectedResponseAnnotationSetNameFalsePoz());
870 
871       // Only one of those radio buttons can be selected
872       if (allFeaturesRadio.isSelected())
873         annotDiff.setKeyFeatureNamesSet(null);
874       if (noFeaturesRadio.isSelected())
875         annotDiff.setKeyFeatureNamesSet(new HashSet());
876       // If someFeaturesRadio is selected, then featureSelectionDialog is not
877       // null because of the collectSomeFeatures() method
878       if (someFeaturesRadio.isSelected())
879         annotDiff.setKeyFeatureNamesSet(
880                    new HashSet(featureSelectionDialog.getSelectedCollection()));
881       String falsePozAnnot = thisAnnotDiffDialog.getSelectedFalsePozAnnot();
882       if ("No annot.".equals(falsePozAnnot))
883             falsePozAnnot = null;
884       annotDiff.setAnnotationTypeForFalsePositive(falsePozAnnot);
885       try{
886         annotDiff.init();
887       } catch (ResourceInstantiationException e){
888         JOptionPane.showMessageDialog(thisAnnotDiffDialog,
889                      e.getMessage() + "\n Annotation diff stopped !",
890                      "Annotation Diff initialization error !",
891                      JOptionPane.ERROR_MESSAGE);
892       }finally {
893         SwingUtilities.invokeLater(new Runnable(){
894           public void run(){
895             doLayout();
896             pack();
897           }// run
898         });//invokeLater
899       }// End try
900     }// run();
901   }//DiffRunner
902 }//AnnotDiffDialog
903