1
15
16 package gate.gui;
17
18 import java.awt.*;
19 import java.awt.event.*;
20 import java.io.*;
21 import java.io.File;
22 import java.io.FileWriter;
23 import java.text.NumberFormat;
24 import java.util.*;
25 import java.util.List;
26 import javax.swing.*;
27 import javax.swing.JTable;
28 import javax.swing.filechooser.FileFilter;
29 import javax.swing.plaf.FileChooserUI;
30 import javax.swing.table.AbstractTableModel;
31 import javax.swing.table.DefaultTableCellRenderer;
32 import gate.*;
33 import gate.Annotation;
34 import gate.Document;
35 import gate.swing.XJTable;
36 import gate.util.*;
37
38
40 public class AnnotationDiffGUI extends JFrame{
41
42 public AnnotationDiffGUI(String title){
43 super(title);
44 initLocalData();
45 initGUI();
46 initListeners();
47 populateGUI();
48 }
49
50 protected void initLocalData(){
51 differ = new AnnotationDiffer();
52 pairings = new ArrayList();
53 significantFeatures = new HashSet();
54 keyDoc = null;
55 resDoc = null;
56 }
57
58
59 protected void initGUI(){
60 getContentPane().setLayout(new GridBagLayout());
61 GridBagConstraints constraints = new GridBagConstraints();
62 constraints.gridy = 0;
64 constraints.gridx = GridBagConstraints.RELATIVE;
65 constraints.weightx = 0;
66 constraints.weighty = 0;
67 constraints.anchor = GridBagConstraints.WEST;
68 constraints.fill = GridBagConstraints.HORIZONTAL;
69 constraints.insets = new Insets(2,4,2,4);
70 constraints.gridx = 1;
72 getContentPane().add(new JLabel("Document"), constraints);
73 constraints.gridx = GridBagConstraints.RELATIVE;
74 getContentPane().add(new JLabel("Annotation Set"), constraints);
75 constraints.gridy = 1;
77 constraints.gridx = GridBagConstraints.RELATIVE;
78 constraints.gridwidth = 1;
79 getContentPane().add(new JLabel("Key:"), constraints);
80 keyDocCombo = new JComboBox();
81 getContentPane().add(keyDocCombo, constraints);
82 keySetCombo = new JComboBox();
83 getContentPane().add(keySetCombo, constraints);
84 getContentPane().add(new JLabel("Annotation Type:"), constraints);
85 annTypeCombo = new JComboBox();
86 constraints.gridwidth = 3;
87 getContentPane().add(annTypeCombo, constraints);
88 constraints.gridwidth = 1;
89 getContentPane().add(new JLabel("F-Measure Weight"), constraints);
90 constraints.gridheight = 2;
91 doDiffBtn = new JButton(new DiffAction());
92 getContentPane().add(doDiffBtn, constraints);
93 constraints.weightx = 1;
94 getContentPane().add(Box.createHorizontalGlue(), constraints);
95 constraints.gridy = 2;
97 constraints.gridx = 0;
98 constraints.gridheight = 1;
99 constraints.weightx = 0;
100 getContentPane().add(new JLabel("Response:"), constraints);
101 constraints.gridx = GridBagConstraints.RELATIVE;
102 resDocCombo = new JComboBox();
103 getContentPane().add(resDocCombo, constraints);
104 resSetCombo = new JComboBox();
105 getContentPane().add(resSetCombo, constraints);
106 getContentPane().add(new JLabel("Features:"), constraints);
107 ButtonGroup btnGrp = new ButtonGroup();
108 allFeaturesBtn = new JRadioButton("All");
109 allFeaturesBtn.setOpaque(false);
110 btnGrp.add(allFeaturesBtn);
111 getContentPane().add(allFeaturesBtn, constraints);
112 someFeaturesBtn = new JRadioButton("Some");
113 someFeaturesBtn.setOpaque(false);
114 btnGrp.add(someFeaturesBtn);
115 getContentPane().add(someFeaturesBtn, constraints);
116 noFeaturesBtn = new JRadioButton("None");
117 noFeaturesBtn.setOpaque(false);
118 btnGrp.add(noFeaturesBtn);
119 getContentPane().add(noFeaturesBtn, constraints);
120 noFeaturesBtn.setSelected(true);
121 weightTxt = new JTextField("1.00");
122 getContentPane().add(weightTxt, constraints);
123 constraints.gridy = 3;
125 constraints.gridx = 0;
126 constraints.gridwidth = 10;
127 constraints.weightx = 1;
128 constraints.weighty = 1;
129 constraints.fill = GridBagConstraints.BOTH;
130 diffTableModel = new DiffTableModel();
131 diffTable = new XJTable(diffTableModel);
132 diffTable.setDefaultRenderer(String.class, new DiffTableCellRenderer());
133 diffTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
134 diffTable.setComparator(DiffTableModel.COL_MATCH, new Comparator(){
135 public int compare(Object o1, Object o2){
136 String label1 = (String)o1;
137 String label2 = (String)o2;
138 int match1 = 0;
139 while(!label1.equals(matchLabel[match1])) match1++;
140 int match2 = 0;
141 while(!label2.equals(matchLabel[match2])) match2++;
142
143 return match1 - match2;
144 }
145 });
146 diffTable.setSortable(true);
147 diffTable.setSortedColumn(DiffTableModel.COL_MATCH);
148 diffTable.setAscending(false);
149 scroller = new JScrollPane(diffTable);
150 getContentPane().add(scroller, constraints);
151
152 resultsPane = new JPanel();
154 resultsPane.setLayout(new GridBagLayout());
155 constraints.gridy = GridBagConstraints.RELATIVE;
157 constraints.gridx = 0;
158 constraints.weightx = 0;
159 constraints.weighty = 0;
160 constraints.gridwidth = 1;
161 constraints.gridheight = 1;
162 constraints.anchor = GridBagConstraints.WEST;
163 constraints.fill = GridBagConstraints.NONE;
164 JLabel lbl = new JLabel("Correct:");
165 lbl.setBackground(diffTable.getBackground());
166 resultsPane.add(lbl, constraints);
167 lbl = new JLabel("Partially Correct:");
168 lbl.setBackground(PARTIALLY_CORRECT_BG);
169 lbl.setOpaque(true);
170 resultsPane.add(lbl, constraints);
171 lbl = new JLabel("Missing:");
172 lbl.setBackground(MISSING_BG);
173 lbl.setOpaque(true);
174 resultsPane.add(lbl, constraints);
175 lbl = new JLabel("False Positives:");
176 lbl.setBackground(FALSE_POZITIVE_BG);
177 lbl.setOpaque(true);
178 resultsPane.add(lbl, constraints);
179
180 constraints.gridx = 1;
182 correctLbl = new JLabel("0");
183 resultsPane.add(correctLbl, constraints);
184 partiallyCorrectLbl = new JLabel("0");
185 resultsPane.add(partiallyCorrectLbl, constraints);
186 missingLbl = new JLabel("0");
187 resultsPane.add(missingLbl, constraints);
188 falsePozLbl = new JLabel("0");
189 resultsPane.add(falsePozLbl, constraints);
190
191 constraints.gridx = 2;
193 constraints.insets = new Insets(4, 30, 4, 4);
194 resultsPane.add(Box.createGlue());
195 lbl = new JLabel("Strict:");
196 resultsPane.add(lbl, constraints);
197 lbl = new JLabel("Lenient:");
198 resultsPane.add(lbl, constraints);
199 lbl = new JLabel("Average:");
200 resultsPane.add(lbl, constraints);
201
202 constraints.gridx = 3;
204 constraints.insets = new Insets(4, 4, 4, 4);
205 lbl = new JLabel("Recall");
206 resultsPane.add(lbl, constraints);
207 recallStrictLbl = new JLabel("0.0000");
208 resultsPane.add(recallStrictLbl, constraints);
209 recallLenientLbl = new JLabel("0.0000");
210 resultsPane.add(recallLenientLbl, constraints);
211 recallAveLbl = new JLabel("0.0000");
212 resultsPane.add(recallAveLbl, constraints);
213
214 constraints.gridx = 4;
216 lbl = new JLabel("Precision");
217 resultsPane.add(lbl, constraints);
218 precisionStrictLbl = new JLabel("0.0000");
219 resultsPane.add(precisionStrictLbl, constraints);
220 precisionLenientLbl = new JLabel("0.0000");
221 resultsPane.add(precisionLenientLbl, constraints);
222 precisionAveLbl = new JLabel("0.0000");
223 resultsPane.add(precisionAveLbl, constraints);
224
225 constraints.gridx = 5;
227 lbl = new JLabel("F-Measure");
228 resultsPane.add(lbl, constraints);
229 fmeasureStrictLbl = new JLabel("0.0000");
230 resultsPane.add(fmeasureStrictLbl, constraints);
231 fmeasureLenientLbl = new JLabel("0.0000");
232 resultsPane.add(fmeasureLenientLbl, constraints);
233 fmeasureAveLbl = new JLabel("0.0000");
234 resultsPane.add(fmeasureAveLbl, constraints);
235
236 constraints.gridx = 6;
238 resultsPane.add(new JButton(new HTMLExportAction()), constraints);
239
240
243
244 constraints.gridy = 4;
246 constraints.gridx = 0;
247 constraints.weightx = 0;
248 constraints.weighty = 0;
249 constraints.gridwidth = 9;
250 constraints.gridheight = 1;
251 constraints.anchor = GridBagConstraints.WEST;
252 constraints.fill = GridBagConstraints.NONE;
253 getContentPane().add(resultsPane, constraints);
254
255
256 Color background = diffTable.getBackground();
258 getContentPane().setBackground(background);
259 scroller.setBackground(background);
260 scroller.getViewport().setBackground(background);
261 resultsPane.setBackground(background);
262
263 featureslistModel = new DefaultListModel();
264 featuresList = new JList(featureslistModel);
265 featuresList.
266 setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
267 }
268
269 protected void initListeners(){
270 keyDocCombo.addActionListener(new ActionListener(){
271 public void actionPerformed(ActionEvent evt){
272 Document newDoc = (Document)documents.get(keyDocCombo.getSelectedIndex());
273 if(keyDoc != newDoc){
274 pairings.clear();
275 diffTableModel.fireTableDataChanged();
276 keyDoc = newDoc;
277 keySets = new ArrayList();
278 List keySetNames = new ArrayList();
279 keySets.add(keyDoc.getAnnotations());
280 keySetNames.add("[Default set]");
281 Iterator setIter = keyDoc.getNamedAnnotationSets().keySet().iterator();
282 while(setIter.hasNext()){
283 String name = (String)setIter.next();
284 keySetNames.add(name);
285 keySets.add(keyDoc.getAnnotations(name));
286 }
287 keySetCombo.setModel(new DefaultComboBoxModel(keySetNames.toArray()));
288 if(!keySetNames.isEmpty())keySetCombo.setSelectedIndex(0);
289
290 }
291 }
292 });
293
294 resDocCombo.addActionListener(new ActionListener(){
295 public void actionPerformed(ActionEvent evt){
296 Document newDoc = (Document)documents.get(resDocCombo.getSelectedIndex());
297 if(resDoc != newDoc){
298 resDoc = newDoc;
299 pairings.clear();
300 diffTableModel.fireTableDataChanged();
301 resSets = new ArrayList();
302 List resSetNames = new ArrayList();
303 resSets.add(resDoc.getAnnotations());
304 resSetNames.add("[Default set]");
305 Iterator setIter = resDoc.getNamedAnnotationSets().keySet().iterator();
306 while(setIter.hasNext()){
307 String name = (String)setIter.next();
308 resSetNames.add(name);
309 resSets.add(resDoc.getAnnotations(name));
310 }
311 resSetCombo.setModel(new DefaultComboBoxModel(resSetNames.toArray()));
312 if(!resSetNames.isEmpty())resSetCombo.setSelectedIndex(0);
313
314 }
315 }
316 });
317
318
321 ActionListener setComboActionListener = new ActionListener(){
322 public void actionPerformed(ActionEvent evt){
323 keySet = keySets == null || keySets.isEmpty()?
324 null :
325 (AnnotationSet)keySets.get(keySetCombo.getSelectedIndex());
326 resSet = resSets == null || resSets.isEmpty()?
327 null :
328 (AnnotationSet)resSets.get(resSetCombo.getSelectedIndex());
329 Set keyTypes = (keySet == null || keySet.isEmpty()) ?
330 new HashSet() : keySet.getAllTypes();
331 Set resTypes = (resSet == null || resSet.isEmpty()) ?
332 new HashSet() : resSet.getAllTypes();
333 Set types = new HashSet(keyTypes);
334 types.retainAll(resTypes);
335 List typesList = new ArrayList(types);
336 Collections.sort(typesList);
337 annTypeCombo.setModel(new DefaultComboBoxModel(typesList.toArray()));
338 if(typesList.size() > 0) annTypeCombo.setSelectedIndex(0);
339 }
340 };
341 keySetCombo.addActionListener(setComboActionListener);
342
343 resSetCombo.addActionListener(setComboActionListener);
344
345 someFeaturesBtn.addActionListener(new ActionListener(){
346 public void actionPerformed(ActionEvent evt){
347 if(someFeaturesBtn.isSelected()){
348 if(keySet == null || keySet.isEmpty() ||
349 annTypeCombo.getSelectedItem() == null) return;
350 Iterator annIter = keySet.
351 get((String)annTypeCombo.getSelectedItem()).iterator();
352 Set featureSet = new HashSet();
353 while(annIter.hasNext()){
354 Annotation ann = (Annotation)annIter.next();
355 Map someFeatures = ann.getFeatures();
356 if(someFeatures != null) featureSet.addAll(someFeatures.keySet());
357 }
358 List featureLst = new ArrayList(featureSet);
359 Collections.sort(featureLst);
360 featureslistModel.clear();
361 Iterator featIter = featureLst.iterator();
362 int index = 0;
363 while(featIter.hasNext()){
364 String aFeature = (String)featIter.next();
365 featureslistModel.addElement(aFeature);
366 if(significantFeatures.contains(aFeature))
367 featuresList.addSelectionInterval(index, index);
368 index ++;
369 }
370 int ret = JOptionPane.showConfirmDialog(AnnotationDiffGUI.this,
371 new JScrollPane(featuresList),
372 "Select features",
373 JOptionPane.OK_CANCEL_OPTION,
374 JOptionPane.QUESTION_MESSAGE);
375 if(ret == JOptionPane.OK_OPTION){
376 significantFeatures.clear();
377 int[] selIdxs = featuresList.getSelectedIndices();
378 for(int i = 0; i < selIdxs.length; i++){
379 significantFeatures.add(featureslistModel.get(selIdxs[i]));
380 }
381 }
382 }
383 }
384 });
385 }
386
387
388 public void pack(){
389 super.pack();
390
391 setSize(getWidth(), getHeight() + 100);
392 }
393 protected void populateGUI(){
394 try{
395 documents = Gate.getCreoleRegister().getAllInstances("gate.Document");
396 }catch(GateException ge){
397 throw new GateRuntimeException(ge);
398 }
399 List documentNames = new ArrayList(documents.size());
400 for(int i =0; i < documents.size(); i++){
401 Document doc = (Document)documents.get(i);
402 documentNames.add(doc.getName());
403 }
404 keyDocCombo.setModel(new DefaultComboBoxModel(documentNames.toArray()));
405 resDocCombo.setModel(new DefaultComboBoxModel(documentNames.toArray()));
406 if(!documents.isEmpty()){
407 keyDocCombo.setSelectedIndex(0);
408 resDocCombo.setSelectedIndex(0);
409 }
410 }
411
412
413 protected class DiffAction extends AbstractAction{
414 public DiffAction(){
415 super("Do Diff");
416 putValue(SHORT_DESCRIPTION, "Performs the diff");
417 }
418
419 public void actionPerformed(ActionEvent evt){
420 Set keys = keySet.get((String)annTypeCombo.getSelectedItem());
421 Set responses = resSet.get((String)annTypeCombo.getSelectedItem());
422 if(keys == null) keys = new HashSet();
423 if(responses == null) responses = new HashSet();
424 if(someFeaturesBtn.isSelected())
425 differ.setSignificantFeaturesSet(significantFeatures);
426 else if(allFeaturesBtn.isSelected())
427 differ.setSignificantFeaturesSet(null);
428 else differ.setSignificantFeaturesSet(new HashSet());
429 pairings.clear();
430 pairings.addAll(differ.calculateDiff(keys, responses));
431 diffTableModel.fireTableDataChanged();
432 correctLbl.setText(Integer.toString(differ.getCorrectMatches()));
433 partiallyCorrectLbl.setText(
434 Integer.toString(differ.getPartiallyCorrectMatches()));
435 missingLbl.setText(Integer.toString(differ.getMissing()));
436 falsePozLbl.setText(Integer.toString(differ.getSpurious()));
437
438 NumberFormat formatter = NumberFormat.getInstance();
439 formatter.setMaximumFractionDigits(4);
440 formatter.setMinimumFractionDigits(2);
441 recallStrictLbl.setText(formatter.format(differ.getRecallStrict()));
442 recallLenientLbl.setText(formatter.format(differ.getRecallLenient()));
443 recallAveLbl.setText(formatter.format(differ.getRecallAverage()));
444 precisionStrictLbl.setText(formatter.format(differ.getPrecisionStrict()));
445 precisionLenientLbl.setText(formatter.format(differ.getPrecisionLenient()));
446 precisionAveLbl.setText(formatter.format(differ.getPrecisionAverage()));
447
448 double weight = Double.parseDouble(weightTxt.getText());
449 fmeasureStrictLbl.setText(formatter.format(differ.getFMeasureStrict(weight)));
450 fmeasureLenientLbl.setText(formatter.format(differ.getFMeasureLenient(weight)));
451 fmeasureAveLbl.setText(formatter.format(differ.getFMeasureAverage(weight)));
452 }
453 }
454
455 protected class HTMLExportAction extends AbstractAction{
456 public HTMLExportAction(){
457 super("Export to HTML");
458 }
459 public void actionPerformed(ActionEvent evt){
460 JFileChooser fileChooser = MainFrame.getFileChooser();
461 File currentFile = fileChooser.getSelectedFile();
462 String nl = Strings.getNl();
463 String parent = (currentFile != null) ? currentFile.getParent() :
464 System.getProperty("user.home");
465 String fileName = (resDoc.getSourceUrl() != null) ?
466 resDoc.getSourceUrl().getFile() :
467 resDoc.getName();
468 fileName += "_" + annTypeCombo.getSelectedItem().toString();
469 fileName += ".html";
470 fileChooser.setSelectedFile(new File(parent, fileName));
471 ExtensionFileFilter fileFilter = new ExtensionFileFilter();
472 fileFilter.addExtension(".html");
473 fileChooser.setFileFilter(fileFilter);
474 fileChooser.setAcceptAllFileFilterUsed(true);
475 fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
476 int res = fileChooser.showSaveDialog(AnnotationDiffGUI.this);
477 if(res == JFileChooser.APPROVE_OPTION){
478 File saveFile = fileChooser.getSelectedFile();
479 try{
480 Writer fw = new BufferedWriter(new FileWriter(saveFile));
481 fw.write(HEADER_1);
483 fw.write(resDoc.getName() + " " +
484 annTypeCombo.getSelectedItem().toString() +
485 " annotations");
486 fw.write(HEADER_2 + nl);
487 fw.write("<H2>Annotation Diff - comparing " +
488 annTypeCombo.getSelectedItem().toString() +
489 " annotations" + "</H2>");
490 fw.write("<TABLE cellpadding=\"5\" border=\"0\"");
491 fw.write(nl);
492 fw.write("<TR>" + nl);
493 fw.write("\t<TH align=\"left\"> </TH>" + nl);
494 fw.write("\t<TH align=\"left\">Document</TH>" + nl);
495 fw.write("\t<TH align=\"left\">Annotation Set</TH>" + nl);
496 fw.write("</TR>" + nl);
497
498 fw.write("<TR>" + nl);
499 fw.write("\t<TH align=\"left\">Key</TH>" + nl);
500 fw.write("\t<TD align=\"left\">" + keyDoc.getName() + "</TD>" + nl);
501 fw.write("\t<TD align=\"left\">" + keySet.getName() + "</TD>" + nl);
502 fw.write("</TR>" + nl);
503 fw.write("<TR>" + nl);
504 fw.write("\t<TH align=\"left\">Response</TH>" + nl);
505 fw.write("\t<TD align=\"left\">" + resDoc.getName() + "</TD>" + nl);
506 fw.write("\t<TD align=\"left\">" + resSet.getName() + "</TD>" + nl);
507 fw.write("</TR>" + nl);
508 fw.write("</TABLE>" + nl);
509 fw.write("<BR><BR><BR>" + nl);
510 java.text.NumberFormat format = java.text.NumberFormat.getInstance();
512 format.setMaximumFractionDigits(4);
513 fw.write("Recall: " + format.format(differ.getRecallStrict()) + "<br>" + nl);
514 fw.write("Precision: " + format.format(differ.getPrecisionStrict()) + "<br>" + nl);
515 fw.write("F-measure: " + format.format(differ.getFMeasureStrict(1)) + "<br>" + nl);
516 fw.write("<br>");
517 fw.write("Correct matches: " + differ.getCorrectMatches() + "<br>" + nl);
518 fw.write("Partially Correct matches: " +
519 differ.getPartiallyCorrectMatches() + "<br>" + nl);
520 fw.write("Missing: " + differ.getMissing() + "<br>" + nl);
521 fw.write("False positives: " + differ.getSpurious() + "<br>" + nl);
522 int[] cols = new int[diffTableModel.getColumnCount()];
525 int maxColIdx = -1;
526 for(int i = 0; i < cols.length; i++){
527 if(!diffTable.isColumnHidden(i)){
528 maxColIdx ++;
529 cols[maxColIdx] = i;
530 }
531 }
532 fw.write(HEADER_3 + nl + "<TR>" + nl);
533 for(int col = 0; col <= maxColIdx; col++){
534 fw.write("\t<TH align=\"left\">" + diffTable.getColumnName(cols[col]) +
535 "</TH>" + nl);
536 }
537 fw.write("</TR>");
538 int rowCnt = diffTableModel.getRowCount();
539 for(int row = 0; row < rowCnt; row ++){
540 fw.write("<TR>");
541 for(int col = 0; col <= maxColIdx; col++){
542 Color bgCol = diffTableModel.getBackgroundAt(
543 diffTable.rowViewToModel(row),
544 diffTable.convertColumnIndexToModel(cols[col]));
545 fw.write("\t<TD bgcolor=\"#" +
546 Integer.toHexString(bgCol.getRGB()).substring(2) +
547 "\">" +
548 diffTable.getValueAt(row, cols[col]) +
549 "</TD>" + nl);
550 }
551 fw.write("</TR>");
552 }
553 fw.write(FOOTER);
554 fw.flush();
555 fw.close();
556
557 }catch(IOException ioe){
558 JOptionPane.showMessageDialog(AnnotationDiffGUI.this, ioe.toString(),
559 "GATE", JOptionPane.ERROR_MESSAGE);
560 ioe.printStackTrace();
561 }
562 }
563 }
564
565 static final String HEADER_1 = "<html><head><title>";
566 static final String HEADER_2 = "</title></head><body>";
567 static final String HEADER_3 = "<table cellpadding=\"0\" border=\"1\">";
568 static final String FOOTER = "</table></body></html>";
569 }
570
571 protected class DiffTableCellRenderer extends DefaultTableCellRenderer{
572 public Component getTableCellRendererComponent(JTable table,
573 Object value,
574 boolean isSelected,
575 boolean hasFocus,
576 int row,
577 int column){
578 Component res = super.getTableCellRendererComponent(table,
579 value, false, hasFocus, row, column);
580 res.setBackground(isSelected ? table.getSelectionBackground() :
581 diffTableModel.getBackgroundAt(diffTable.rowViewToModel(row),
582 column));
583 res.setForeground(isSelected ? table.getSelectionForeground() :
584 table.getForeground());
585 return res;
586 }
587 }
588
589 protected class DiffTableModel extends AbstractTableModel{
590 public int getRowCount(){
591 return pairings.size();
592 }
593
594 public Class getColumnClass(int columnIndex){
595 return String.class;
596 }
597
598 public int getColumnCount(){
599 return COL_CNT;
600 }
601
602 public String getColumnName(int column){
603 switch(column){
604 case COL_KEY_START: return "Start";
605 case COL_KEY_END: return "End";
606 case COL_KEY_STRING: return "Key";
607 case COL_KEY_FEATURES: return "Features";
608 case COL_MATCH: return "";
609 case COL_RES_START: return "Start";
610 case COL_RES_END: return "End";
611 case COL_RES_STRING: return "Response";
612 case COL_RES_FEATURES: return "Features";
613 default: return "?";
614 }
615 }
616
617 public Color getBackgroundAt(int row, int column){
618 AnnotationDiffer.Pairing pairing =
619 (AnnotationDiffer.Pairing)pairings.get(row);
620 Color colKey = pairing.getType() == AnnotationDiffer.CORRECT ?
621 diffTable.getBackground() :
622 (pairing.getType() == AnnotationDiffer.PARTIALLY_CORRECT ?
623 PARTIALLY_CORRECT_BG :
624 MISSING_BG);
625 if(pairing.getKey() == null) colKey = diffTable.getBackground();
626 Color colRes = pairing.getType() == AnnotationDiffer.CORRECT ?
627 diffTable.getBackground() :
628 (pairing.getType() == AnnotationDiffer.PARTIALLY_CORRECT ?
629 PARTIALLY_CORRECT_BG :
630 FALSE_POZITIVE_BG);
631 if(pairing.getResponse() == null) colRes = diffTable.getBackground();
632 switch(column){
633 case COL_KEY_START: return colKey;
634 case COL_KEY_END: return colKey;
635 case COL_KEY_STRING: return colKey;
636 case COL_KEY_FEATURES: return colKey;
637 case COL_MATCH: return diffTable.getBackground();
638 case COL_RES_START: return colRes;
639 case COL_RES_END: return colRes;
640 case COL_RES_STRING: return colRes;
641 case COL_RES_FEATURES: return colRes;
642 default: return diffTable.getBackground();
643 }
644 }
645
646 public Object getValueAt(int row, int column){
647 AnnotationDiffer.Pairing pairing =
648 (AnnotationDiffer.Pairing)pairings.get(row);
649 Annotation key = pairing.getKey();
650 String keyStr = "";
651 try{
652 if(key != null && keyDoc != null){
653 keyStr = keyDoc.getContent().getContent(key.getStartNode().getOffset(),
654 key.getEndNode().getOffset()).toString();
655 }
656 }catch(InvalidOffsetException ioe){
657 throw new GateRuntimeException(ioe);
659 }
660 Annotation res = pairing.getResponse();
661 String resStr = "";
662 try{
663 if(res != null && resDoc != null){
664 resStr = resDoc.getContent().getContent(res.getStartNode().getOffset(),
665 res.getEndNode().getOffset()).toString();
666 }
667 }catch(InvalidOffsetException ioe){
668 throw new GateRuntimeException(ioe);
670 }
671
672 switch(column){
673 case COL_KEY_START: return key == null ? "" :
674 key.getStartNode().getOffset().toString();
675 case COL_KEY_END: return key == null ? "" :
676 key.getEndNode().getOffset().toString();
677 case COL_KEY_STRING: return keyStr;
678 case COL_KEY_FEATURES: return key == null ? "" :
679 key.getFeatures().toString();
680 case COL_MATCH: return matchLabel[pairing.getType()];
681 case COL_RES_START: return res == null ? "" :
682 res.getStartNode().getOffset().toString();
683 case COL_RES_END: return res == null ? "" :
684 res.getEndNode().getOffset().toString();
685 case COL_RES_STRING: return resStr;
686 case COL_RES_FEATURES: return res == null ? "" :
687 res.getFeatures().toString();
688 default: return "?";
689 }
690 }
691
692 protected static final int COL_CNT = 9;
693 protected static final int COL_KEY_START = 0;
694 protected static final int COL_KEY_END = 1;
695 protected static final int COL_KEY_STRING = 2;
696 protected static final int COL_KEY_FEATURES = 3;
697 protected static final int COL_MATCH = 4;
698 protected static final int COL_RES_START = 5;
699 protected static final int COL_RES_END = 6;
700 protected static final int COL_RES_STRING = 7;
701 protected static final int COL_RES_FEATURES = 8;
702 }
703
704 protected AnnotationDiffer differ;
705 protected List pairings;
706 protected Document keyDoc;
707 protected Document resDoc;
708 protected Set significantFeatures;
709 protected List documents;
710 protected List keySets;
711 protected List resSets;
712 protected AnnotationSet keySet;
713 protected AnnotationSet resSet;
714
715 protected JList featuresList;
716 protected DefaultListModel featureslistModel;
717 protected DiffTableModel diffTableModel;
718 protected XJTable diffTable;
719 protected JScrollPane scroller;
720 protected JComboBox keyDocCombo;
721 protected JComboBox keySetCombo;
722 protected JComboBox annTypeCombo;
723 protected JComboBox resDocCombo;
724 protected JComboBox resSetCombo;
725
726 protected JRadioButton allFeaturesBtn;
727 protected JRadioButton someFeaturesBtn;
728 protected JRadioButton noFeaturesBtn;
729 protected JTextField weightTxt;
730 protected JButton doDiffBtn;
731
732 protected JPanel resultsPane;
733 protected JLabel correctLbl;
734 protected JLabel partiallyCorrectLbl;
735 protected JLabel missingLbl;
736 protected JLabel falsePozLbl;
737 protected JLabel recallStrictLbl;
738 protected JLabel precisionStrictLbl;
739 protected JLabel fmeasureStrictLbl;
740 protected JLabel recallLenientLbl;
741 protected JLabel precisionLenientLbl;
742 protected JLabel fmeasureLenientLbl;
743 protected JLabel recallAveLbl;
744 protected JLabel precisionAveLbl;
745 protected JLabel fmeasureAveLbl;
746
747 protected static final Color PARTIALLY_CORRECT_BG = new Color(173,215,255);
748 protected static final Color MISSING_BG = new Color(255,173,181);;
749 protected static final Color FALSE_POZITIVE_BG = new Color(255,231,173);
750 protected static final String[] matchLabel;
751 static{
752 matchLabel = new String[3];
753 matchLabel[AnnotationDiffer.CORRECT] = "=";
754 matchLabel[AnnotationDiffer.PARTIALLY_CORRECT] = "~";
755 matchLabel[AnnotationDiffer.WRONG] = "!=";
756 }
757 }
758