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.21 2001/10/12 17:20:57 cursu 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     typesComboBox.setEditable(false);
270     typesComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
271     // init its label
272     typesLabel = new JLabel("Select annot. type");
273     typesLabel.setFont(typesLabel.getFont().deriveFont(Font.BOLD));
274     typesLabel.setOpaque(true);
275     typesLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
276 
277     // init falsePozTypeComboBox
278     falsePozTypeComboBox = new JComboBox(falsePozTypes.toArray());
279     falsePozTypeComboBox.setEditable(false);
280     falsePozTypeComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
281     // init its label
282     falsePozLabel = new JLabel("Select annot. type for FalsePoz");
283     falsePozLabel.setFont(falsePozLabel.getFont().deriveFont(Font.BOLD));
284     falsePozLabel.setOpaque(true);
285     falsePozLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
286 
287     // init weightTextField
288     weightTextField = new JTextField(
289                               (new Double(AnnotationDiff.weight)).toString());
290     weightTextField.setAlignmentX(Component.LEFT_ALIGNMENT);
291     // init its label
292     weightLabel = new JLabel("Weight for F-Measure");
293     weightLabel.setFont(falsePozLabel.getFont().deriveFont(Font.BOLD));
294     weightLabel.setOpaque(true);
295     weightLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
296 
297     // Set initial dimmension for weightTextField
298     Dimension d = new Dimension(weightLabel.getPreferredSize().width,
299                                     weightTextField.getPreferredSize().height);
300     weightTextField.setMinimumSize(d);
301     weightTextField.setMaximumSize(d);
302     weightTextField.setPreferredSize(d);
303 
304     // evaluate button
305     evalButton = new JButton("Evaluate");
306     evalButton.setFont(evalButton.getFont().deriveFont(Font.BOLD));
307 
308     // Some features radio Button
309     someFeaturesRadio = new JRadioButton("Some");
310     someFeaturesRadio.setToolTipText("Select some features from the key"+
311       " annotation set, that will be taken into consideration"+
312       " in the diff process.");
313     // No features RB
314     noFeaturesRadio = new JRadioButton("None");
315     noFeaturesRadio.setToolTipText("No features from the key"+
316       " annotation set will be taken into consideration"+
317       " in the diff process.");
318     // All features RB
319     allFeaturesRadio = new JRadioButton("All");
320     allFeaturesRadio.setSelected(true);
321     allFeaturesRadio.setToolTipText("All features from the key"+
322       " annotation set will be taken into consideration"+
323       " in the diff process.");
324     // Add radio buttons to the group
325     groupRadios = new ButtonGroup();
326     groupRadios.add(allFeaturesRadio);
327     groupRadios.add(someFeaturesRadio);
328     groupRadios.add(noFeaturesRadio);
329     // The label for the Features radio buttons group
330     selectFeaturesLabel = new JLabel("Features");
331     selectFeaturesLabel.setFont(falsePozLabel.getFont().deriveFont(Font.BOLD));
332     selectFeaturesLabel.setOpaque(true);
333     selectFeaturesLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
334     // ***************************************************************
335     // Put all those components at their place
336     // ***************************************************************
337     Box northBox = new Box(BoxLayout.X_AXIS);
338     // Arange Key Document components
339     Box currentBox = new Box(BoxLayout.Y_AXIS);
340     currentBox.add(keyLabel);
341     currentBox.add(keyDocComboBox);
342     currentBox.add(Box.createVerticalStrut(10));
343     currentBox.add(responseLabel);
344     currentBox.add(responseDocComboBox);
345     northBox.add(currentBox);
346 
347     northBox.add(Box.createRigidArea(new Dimension(10,0)));
348 
349     // Arange annotation set components
350     currentBox = new Box(BoxLayout.Y_AXIS);
351     currentBox.add(keyDocAnnotSetLabel);
352     currentBox.add(keyDocAnnotSetComboBox);
353     currentBox.add(Box.createVerticalStrut(10));
354     currentBox.add(responseDocAnnotSetLabel);
355     currentBox.add(responseDocAnnotSetComboBox);
356     northBox.add(currentBox);
357 
358     northBox.add(Box.createRigidArea(new Dimension(10,0)));
359 
360     // Arange annotation types components
361     currentBox = new Box(BoxLayout.Y_AXIS);
362     currentBox.add(typesLabel);
363     currentBox.add(typesComboBox);
364     northBox.add(currentBox);
365 
366     northBox.add(Box.createRigidArea(new Dimension(10,0)));
367 
368     // Arrange the radio buttons
369     currentBox = new Box(BoxLayout.Y_AXIS);
370     currentBox.add(selectFeaturesLabel);
371     currentBox.add(allFeaturesRadio);
372     currentBox.add(someFeaturesRadio);
373     currentBox.add(noFeaturesRadio);
374     northBox.add(currentBox);
375 
376     northBox.add(Box.createRigidArea(new Dimension(10,0)));
377 
378     // Arange F-Measure weight components
379     currentBox = new Box(BoxLayout.Y_AXIS);
380     currentBox.add(weightLabel);
381     currentBox.add(weightTextField);
382     northBox.add(currentBox);
383 
384     northBox.add(Box.createRigidArea(new Dimension(10,0)));
385 
386     // Arange false poz components
387     currentBox = new Box(BoxLayout.Y_AXIS);
388     currentBox.add(falsePozLabel);
389     currentBox.add(falsePozTypeComboBox);
390     currentBox.add(Box.createVerticalStrut(10));
391     currentBox.add(responseDocAnnotSetFalsePozLabel);
392     currentBox.add(responseDocAnnotSetFalsePozComboBox);
393     northBox.add(currentBox);
394 
395     northBox.add(Box.createRigidArea(new Dimension(10,0)));
396     northBox.add(evalButton);
397 
398     initKeyAnnotSetNames();
399     initResponseAnnotSetNames();
400     initAnnotTypes();
401     initAnnotTypesFalsePoz();
402 
403     this.getContentPane().setLayout(new BoxLayout(this.getContentPane(),
404                                                             BoxLayout.Y_AXIS));
405     Dimension maxDimm = Toolkit.getDefaultToolkit().getScreenSize();
406     Dimension newDim = new Dimension(maxDimm.width/3, maxDimm.height/3);
407     JScrollPane upperScrolPane = new JScrollPane(northBox);
408     upperScrolPane.getViewport().
409                     putClientProperty("EnableWindowBlit", new Boolean(true));
410     JScrollPane lowerScrolPane = new JScrollPane(annotDiff);
411     lowerScrolPane.getViewport().
412                     putClientProperty("EnableWindowBlit", new Boolean(true));
413     lowerScrolPane.setMaximumSize(newDim);
414     lowerScrolPane.setMinimumSize(newDim);
415     lowerScrolPane.setPreferredSize(newDim);
416 
417     jSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
418                                upperScrolPane,
419                                lowerScrolPane);
420     jSplit.setOneTouchExpandable(true);
421     jSplit.setOpaque(true);
422     jSplit.setAlignmentY(Component.TOP_ALIGNMENT);
423     this.getContentPane().add(jSplit);
424     this.pack();
425     ////////////////////////////////
426     // Center it on screen
427     ///////////////////////////////
428     Dimension ownerSize;
429     Point ownerLocation;
430     if(getOwner() == null){
431       ownerSize = Toolkit.getDefaultToolkit().getScreenSize();
432       ownerLocation = new Point(0, 0);
433     }else{
434       ownerSize = getOwner().getSize();
435       ownerLocation = getOwner().getLocation();
436       if(ownerSize.height == 0 ||
437          ownerSize.width == 0 ||
438          !getOwner().isVisible()){
439         ownerSize = Toolkit.getDefaultToolkit().getScreenSize();
440         ownerLocation = new Point(0, 0);
441       }
442     }
443     //Center the window
444     Dimension frameSize = getSize();
445     if (frameSize.height > ownerSize.height)
446       frameSize.height = ownerSize.height;
447     if (frameSize.width > ownerSize.width)
448       frameSize.width = ownerSize.width;
449     setLocation(ownerLocation.x + (ownerSize.width - frameSize.width) / 2,
450                 ownerLocation.y + (ownerSize.height - frameSize.height) / 2);
451 
452   }//initGuiComponents
453 
454   /** This method is called when the user want to close the tool. See
455     * initListeners() method for more details
456     */
457   void this_windowClosing(WindowEvent e){
458     this.setVisible(false);
459   }//this_windowClosing();
460 
461   /** This method starts AnnotationDiff tool in a separate thread.*/
462   private void doDiff(){
463     try{
464       Double d = new Double(thisAnnotDiffDialog.getCurrentWeight());
465       AnnotationDiff.weight = d.doubleValue();
466     }catch (NumberFormatException e){
467         JOptionPane.showMessageDialog(thisAnnotDiffDialog,
468                      "The weight for F-Measure should be a double !",
469                      "Annotation Diff initialization error !",
470                      JOptionPane.ERROR_MESSAGE);
471         return;
472     }// End try
473     Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
474                                new DiffRunner(),
475                                "AnnotDiffDialog1");
476     thread.setPriority(Thread.MIN_PRIORITY);
477     thread.start();
478   }//doDiff();
479 
480   /**This one initializes the listeners fot the GUI components */
481   public void initListeners(){
482 
483     this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
484     this.addWindowListener(new java.awt.event.WindowAdapter() {
485       public void windowClosing(WindowEvent e) {
486         this_windowClosing(e);
487       }// windowClosing();
488     });// addWindowListener();
489 
490     evalButton.addActionListener(new java.awt.event.ActionListener() {
491       public void actionPerformed(ActionEvent e) {
492          thisAnnotDiffDialog.doDiff();
493       }// actionPerformed();
494     });//addActionListener();
495 
496     keyDocComboBox.addActionListener(new ActionListener() {
497       public void actionPerformed(ActionEvent e) {
498         initKeyAnnotSetNames();
499         initAnnotTypes();
500       }// actionPerformed();
501     });//addActionListener();
502 
503     responseDocComboBox.addActionListener(new ActionListener() {
504       public void actionPerformed(ActionEvent e) {
505         initResponseAnnotSetNames();
506         initAnnotTypes();
507       }// actionPerformed();
508     });//addActionListener();
509 
510     keyDocAnnotSetComboBox.addActionListener(new ActionListener() {
511       public void actionPerformed(ActionEvent e) {
512         initAnnotTypes();
513       }// actionPerformed();
514     });//addActionListener();
515 
516     responseDocAnnotSetComboBox.addActionListener(new ActionListener() {
517       public void actionPerformed(ActionEvent e) {
518         initAnnotTypes();
519       }// actionPerformed();
520     });//addActionListener();
521 
522     responseDocAnnotSetFalsePozComboBox.addActionListener(new ActionListener() {
523       public void actionPerformed(ActionEvent e) {
524         initAnnotTypesFalsePoz();
525       }// actionPerformed();
526     });//addActionListener();
527 
528     typesComboBox.addActionListener(new ActionListener() {
529       public void actionPerformed(ActionEvent e){
530         if (featureSelectionDialog != null) featureSelectionDialog = null;
531       }// actionPerformed();
532     });//addActionListener();
533 
534     someFeaturesRadio.addActionListener(new ActionListener() {
535       public void actionPerformed(ActionEvent e){
536         collectSomeFeatures();
537       }// actionPerformed();
538     });//addActionListener();
539 
540   }//initListeners();
541 
542   /** Activates the CollectionSelectionDialog in order to colect those feature
543     * from key that will take part in the diff process
544     */
545   private void collectSomeFeatures(){
546     if (featureSelectionDialog == null){
547       featureSelectionDialog = new CollectionSelectionDialog(
548                                                 thisAnnotDiffDialog,true);
549     }else{
550       featureSelectionDialog.setVisible(true);
551       return;
552     }// End if
553     // For the current annotation type take all the features that appear in the
554     // key set and initialize the featureSelectionDialog
555     gate.Document keyDocument = null;
556     keyDocument = (gate.Document) documentsMap.get(
557                                  (String)keyDocComboBox.getSelectedItem());
558     if (keyDocument == null){
559       JOptionPane.showMessageDialog(this,
560                                     "Select a key document first !",
561                                     "Gate", JOptionPane.ERROR_MESSAGE);
562       featureSelectionDialog = null;
563       return;
564     }//End if
565 
566     AnnotationSet keySet = null;
567     if (keyDocAnnotSetComboBox.getSelectedItem()== null ||
568         keyAnnotationSetMap.get(keyDocAnnotSetComboBox.getSelectedItem())==null)
569       // First add to the keySet all annotations from default set
570       keySet = keyDocument.getAnnotations();
571     else{
572       // Get all types of annotation from the selected keyAnnotationSet
573       AnnotationSet as = (AnnotationSet) keyAnnotationSetMap.get(
574                                   keyDocAnnotSetComboBox.getSelectedItem());
575       keySet = as;
576     }// End if
577     if (keySet == null){
578       JOptionPane.showMessageDialog(this,
579                                     "Select some annotation sets first !",
580                                     "Gate", JOptionPane.ERROR_MESSAGE);
581       featureSelectionDialog = null;
582       return;
583     }// End if
584     AnnotationSchema annotSchema = (AnnotationSchema)
585                                 typesMap.get(typesComboBox.getSelectedItem());
586     if (annotSchema == null){
587       JOptionPane.showMessageDialog(this,
588                                     "Select some annotation types first !",
589                                     "Gate", JOptionPane.ERROR_MESSAGE);
590       featureSelectionDialog = null;
591       return;
592     }// End if
593     AnnotationSet selectedTypeSet = keySet.get(annotSchema.getAnnotationName());
594     Set featureNamesSet = new TreeSet();
595     // Iterate this set and get all feature keys.
596     Iterator selectedTypeIterator = selectedTypeSet.iterator();
597     while(selectedTypeIterator.hasNext()){
598       Annotation a = (Annotation) selectedTypeIterator.next();
599       if (a.getFeatures() != null)
600         featureNamesSet.addAll(a.getFeatures().keySet());
601     }// End while
602     featureSelectionDialog.show("Select features for annotation type \"" +
603         annotSchema.getAnnotationName()+ "\" that would be used in diff proces",
604         featureNamesSet);
605   }//collectSomeFeatures();
606 
607   /** Initializes the annotations for false Poz masure*/
608   private void initAnnotTypesFalsePoz(){
609     gate.Document responseDocument = null;
610     responseDocument = (gate.Document) documentsMap.get(
611                                  (String)responseDocComboBox.getSelectedItem());
612     falsePozTypes.clear();
613     if (responseDocument == null){
614       // init falsePozTypes
615       falsePozTypes.add("No annot.");
616       DefaultComboBoxModel cbm = new DefaultComboBoxModel(falsePozTypes.toArray());
617       falsePozTypeComboBox.setModel(cbm);
618       return;
619     }//End if
620 
621     // Fill the responseSet
622     Set responseSet = null;
623     if (responseDocAnnotSetFalsePozComboBox.getSelectedItem() == null ||
624         responseAnnotationSetMap.get(
625                    responseDocAnnotSetFalsePozComboBox.getSelectedItem())==null)
626         responseSet = new HashSet(
627                               responseDocument.getAnnotations().getAllTypes());
628     else{
629       // Get all types of annotation from the selected responseAnnotationSet
630       AnnotationSet as = (AnnotationSet) responseAnnotationSetMap.get(
631                          responseDocAnnotSetFalsePozComboBox.getSelectedItem());
632       responseSet = new HashSet(as.getAllTypes());
633     }// End if
634 
635     // Init falsePozTypes
636     falsePozTypes.addAll(responseSet);
637     if (falsePozTypes.isEmpty())
638       falsePozTypes.add("No annot.");
639     DefaultComboBoxModel cbm = new DefaultComboBoxModel(falsePozTypes.toArray());
640     falsePozTypeComboBox.setModel(cbm);
641   }//initAnnotTypesFalsePoz();
642 
643   /** Reads the selected keyDocument + the selected responseDocument and
644     * also reads the selected annotation sets from Key and response and
645     * intersects the annotation types. The result is the typesComboBox which
646     * is filled with the intersected types.
647     */
648   private void initAnnotTypes(){
649     gate.Document keyDocument = null;
650     gate.Document responseDocument = null;
651 
652     keyDocument = (gate.Document) documentsMap.get(
653                                  (String)keyDocComboBox.getSelectedItem());
654     responseDocument = (gate.Document) documentsMap.get(
655                                  (String)responseDocComboBox.getSelectedItem());
656 
657     typesMap.clear();
658 
659     if (keyDocument == null || responseDocument == null){
660       // init types map with Type,AnnotationSchema pairs
661       typesMap.put("No annot.",null);
662       ComboBoxModel cbm = new DefaultComboBoxModel(typesMap.keySet().toArray());
663       typesComboBox.setModel(cbm);
664       return;
665     }//End if
666 
667     // Do intersection for annotation types...
668     // First fill the keySet;
669     Set keySet = null;
670     if (keyDocAnnotSetComboBox.getSelectedItem()== null ||
671         keyAnnotationSetMap.get(keyDocAnnotSetComboBox.getSelectedItem())==null)
672       // First add to the keySet all annotations from default set
673       keySet = new HashSet(keyDocument.getAnnotations().getAllTypes());
674     else{
675       // Get all types of annotation from the selected keyAnnotationSet
676       AnnotationSet as = (AnnotationSet) keyAnnotationSetMap.get(
677                                   keyDocAnnotSetComboBox.getSelectedItem());
678       keySet = new HashSet(as.getAllTypes());
679     }// End if
680 
681     // Do the same thing for the responseSet
682     // Fill the responseSet
683     Set responseSet = null;
684     if (responseDocAnnotSetComboBox.getSelectedItem() == null ||
685         responseAnnotationSetMap.get(
686                           responseDocAnnotSetComboBox.getSelectedItem())==null)
687         responseSet = new HashSet(
688                               responseDocument.getAnnotations().getAllTypes());
689     else{
690       // Get all types of annotation from the selected responseAnnotationSet
691       AnnotationSet as = (AnnotationSet) responseAnnotationSetMap.get(
692                                  responseDocAnnotSetComboBox.getSelectedItem());
693       responseSet = new HashSet(as.getAllTypes());
694     }// End if
695 
696     // DO intersection between keySet & responseSet
697     keySet.retainAll(responseSet);
698     Set intersectSet = keySet;
699 
700     Iterator iter = intersectSet.iterator();
701     while (iter.hasNext()){
702       String annotName = (String) iter.next();
703 
704       AnnotationSchema schema = new AnnotationSchema();
705       schema.setAnnotationName(annotName);
706 
707       typesMap.put(annotName,schema);
708     }// while
709 
710     if (typesMap.isEmpty())
711       typesMap.put("No annot.",null);
712 
713     DefaultComboBoxModel cbm = new DefaultComboBoxModel(
714                                               typesMap.keySet().toArray());
715     typesComboBox.setModel(cbm);
716   }//initAnnotTypes();
717 
718   /** Reads the selected keyDocument + the selected responseDocument and fill
719     * the two combo boxes called keyDocAnnotSetComboBox and
720     * responseDocAnnotSetComboBox.
721     */
722   private void initKeyAnnotSetNames(){
723     gate.Document keyDocument = null;
724     keyDocument = (gate.Document) documentsMap.get(
725                                  (String)keyDocComboBox.getSelectedItem());
726     keyAnnotationSetMap.clear();
727 
728     if (keyDocument != null){
729       Map namedAnnotSets = keyDocument.getNamedAnnotationSets();
730       if (namedAnnotSets != null)
731         keyAnnotationSetMap.putAll(namedAnnotSets);
732       keyAnnotationSetMap.put("Default set",null);
733       DefaultComboBoxModel cbm = new DefaultComboBoxModel(
734                                         keyAnnotationSetMap.keySet().toArray());
735       keyDocAnnotSetComboBox.setModel(cbm);
736     }// End if
737   }//initKeyAnnotSetNames();
738 
739   /** Reads the selected responseDocument and fill
740     * the combo box called responseDocAnnotSetFalsePozComboBox as well as
741     * responseDocAnnotSetComboBox.
742     */
743   private void initResponseAnnotSetNames(){
744     gate.Document responseDocument = null;
745     responseDocument = (gate.Document) documentsMap.get(
746                                  (String)responseDocComboBox.getSelectedItem());
747     responseAnnotationSetMap.clear();
748 
749     if (responseDocument != null){
750       Map namedAnnotSets = responseDocument.getNamedAnnotationSets();
751       if (namedAnnotSets != null)
752         responseAnnotationSetMap.putAll(namedAnnotSets);
753       responseAnnotationSetMap.put("Default set",null);
754       DefaultComboBoxModel cbm = new DefaultComboBoxModel(
755                                   responseAnnotationSetMap.keySet().toArray());
756       responseDocAnnotSetComboBox.setModel(cbm);
757       cbm = new DefaultComboBoxModel(
758                                   responseAnnotationSetMap.keySet().toArray());
759       responseDocAnnotSetFalsePozComboBox.setModel(cbm);
760     }// End if
761   }//initResponseAnnotSetNames();
762 
763   /** It returns the selected KEY gate.Document*/
764   public gate.Document getSelectedKeyDocument(){
765     return (gate.Document) documentsMap.get(
766                                 (String)keyDocComboBox.getSelectedItem());
767   }//getSelectedKeyDocument
768 
769   /** It returns the selected RESPONSE gate.Document*/
770   public gate.Document getSelectedResponseDocument(){
771     return (gate.Document) documentsMap.get(
772                                 (String)responseDocComboBox.getSelectedItem());
773   }//getSelectedResponseDocument
774 
775   /** It returns the selected SCHEMA  */
776   public AnnotationSchema getSelectedSchema(){
777     return (AnnotationSchema) typesMap.get(
778                                 (String)typesComboBox.getSelectedItem());
779   }//getSelectedSchema
780 
781   /** It returns the current weight  */
782   public String getCurrentWeight(){
783     return weightTextField.getText();
784   }//getCurrentWeight
785 
786   /** It returns the selected Annotation to calculate the False Pozitive  */
787   public String getSelectedFalsePozAnnot(){
788     return (String) falsePozTypeComboBox.getSelectedItem();
789   }//getSelectedFalsePozAnnot
790 
791   /** It returns the selected key AnnotationSet name. It returns null for the
792     * default annotation set.
793     */
794   public String getSelectedKeyAnnotationSetName(){
795    String asName = (String) keyDocAnnotSetComboBox.getSelectedItem();
796    if ("Default set".equals(asName)) return null;
797    else return asName;
798   }//getSelectedKeyAnnotationSetName()
799 
800   /** It returns the selected response AnnotationSet name.It returns null for the
801     * default annotation set.
802     */
803   public String getSelectedResponseAnnotationSetName(){
804    String asName = (String) responseDocAnnotSetComboBox.getSelectedItem();
805    if ("Default set".equals(asName)) return null;
806    else return asName;
807   }//getSelectedResponseAnnotationSetName()
808 
809   /** It returns the selected response AnnotationSet name for False Poz.
810     * It returns null for the default annotation set.
811     */
812   public String getSelectedResponseAnnotationSetNameFalsePoz(){
813    String asName = (String) responseDocAnnotSetFalsePozComboBox.getSelectedItem();
814    if ("Default set".equals(asName)) return null;
815    else return asName;
816   }//getSelectedResponseAnnotationSetNameFalsePoz()
817 
818   /**  Inner class that adds a tool tip to the combo boxes with key and response
819     *  documents. The tool tip represents the full path of the documents.
820     */
821   class MyCellRenderer extends JLabel implements ListCellRenderer {
822 
823      Color background = null;
824      Color foreground = null;
825      /** Constructs a renderer*/
826      public MyCellRenderer(Color aBackground, Color aForeground){
827          setOpaque(true);
828          background = aBackground;
829          foreground = aForeground;
830      }// MyCellRenderer();
831 
832      /** This method is overridden in order to implement the needed behaviour*/
833      public Component getListCellRendererComponent(
834                                                    JList list,
835                                                    Object value,
836                                                    int index,
837                                                    boolean isSelected,
838                                                    boolean cellHasFocus){
839          // should be done only once...
840          ToolTipManager.sharedInstance().registerComponent(list);
841          setText(value.toString());
842          setBackground(isSelected ? background : Color.white);
843          setForeground(isSelected ? foreground : Color.black);
844          if (isSelected)
845              list.setToolTipText(value.toString());
846          return this;
847      }// getListCellRendererComponent()
848   }//MyCellRenderer
849 
850   /**Inner class used to run an annot. diff in a new thread*/
851   class DiffRunner implements Runnable{
852     /** Constructor */
853     public DiffRunner(){}// DiffRuner
854     /** This method is overridden in order to implement the needed behaviour*/
855     public void run(){
856       annotDiff.setKeyDocument(thisAnnotDiffDialog.getSelectedKeyDocument());
857       annotDiff.setResponseDocument(
858                           thisAnnotDiffDialog.getSelectedResponseDocument());
859       annotDiff.setAnnotationSchema(thisAnnotDiffDialog.getSelectedSchema());
860       annotDiff.setKeyAnnotationSetName(
861                       thisAnnotDiffDialog.getSelectedKeyAnnotationSetName());
862       annotDiff.setResponseAnnotationSetName(
863                   thisAnnotDiffDialog.getSelectedResponseAnnotationSetName());
864       annotDiff.setResponseAnnotationSetNameFalsePoz(
865             thisAnnotDiffDialog.getSelectedResponseAnnotationSetNameFalsePoz());
866 
867       // Only one of those radio buttons can be selected
868       if (allFeaturesRadio.isSelected())
869         annotDiff.setKeyFeatureNamesSet(null);
870       if (noFeaturesRadio.isSelected())
871         annotDiff.setKeyFeatureNamesSet(new HashSet());
872       // If someFeaturesRadio is selected, then featureSelectionDialog is not
873       // null because of the collectSomeFeatures() method
874       if (someFeaturesRadio.isSelected())
875         annotDiff.setKeyFeatureNamesSet(
876                    new HashSet(featureSelectionDialog.getSelectedCollection()));
877       String falsePozAnnot = thisAnnotDiffDialog.getSelectedFalsePozAnnot();
878       if ("No annot.".equals(falsePozAnnot))
879             falsePozAnnot = null;
880       annotDiff.setAnnotationTypeForFalsePositive(falsePozAnnot);
881       try{
882         annotDiff.init();
883       } catch (ResourceInstantiationException e){
884         JOptionPane.showMessageDialog(thisAnnotDiffDialog,
885                      e.getMessage() + "\n Annotation diff stopped !",
886                      "Annotation Diff initialization error !",
887                      JOptionPane.ERROR_MESSAGE);
888       }finally {
889         SwingUtilities.invokeLater(new Runnable(){
890           public void run(){
891             doLayout();
892             pack();
893           }// run
894         });//invokeLater
895       }// End try
896     }// run();
897   }//DiffRunner
898 }//AnnotDiffDialog
899