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