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