001 /*
002 * The contents of this file are subject to the Mozilla Public
003 * License Version 1.1 (the "License"); you may not use this file
004 * except in compliance with the License. You may obtain a copy of
005 * the License at http://www.mozilla.org/MPL/
006 *
007 * Software distributed under the License is distributed on an "AS
008 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
009 * implied. See the License for the specific language governing
010 * rights and limitations under the License.
011 *
012 * The Original Code is Knowtator.
013 *
014 * The Initial Developer of the Original Code is University of Colorado.
015 * Copyright (C) 2005 - 2008. All Rights Reserved.
016 *
017 * Knowtator was developed by the Center for Computational Pharmacology
018 * (http://compbio.uchcs.edu) at the University of Colorado Health
019 * Sciences Center School of Medicine with support from the National
020 * Library of Medicine.
021 *
022 * Current information about Knowtator can be obtained at
023 * http://knowtator.sourceforge.net/
024 *
025 * Contributor(s):
026 * Philip V. Ogren <philip@ogren.info> (Original Author)
027 * Brant Barney <brant.barney@hsc.utah.edu>
028 */
029
030 package edu.uchsc.ccp.knowtator;
031
032 import java.awt.BorderLayout;
033 import java.awt.Component;
034 import java.awt.Container;
035 import java.awt.Dimension;
036 import java.awt.Font;
037 import java.awt.GridBagConstraints;
038 import java.awt.GridBagLayout;
039 import java.awt.Insets;
040 import java.awt.Toolkit;
041 import java.awt.event.ActionEvent;
042 import java.awt.event.ActionListener;
043 import java.awt.event.KeyEvent;
044 import java.awt.event.MouseAdapter;
045 import java.awt.event.MouseEvent;
046 import java.awt.event.MouseListener;
047 import java.io.File;
048 import java.io.IOException;
049 import java.net.URI;
050 import java.util.ArrayList;
051 import java.util.Collection;
052 import java.util.Comparator;
053 import java.util.HashMap;
054 import java.util.List;
055 import java.util.Map;
056 import java.util.Set;
057
058 import javax.swing.AbstractAction;
059 import javax.swing.BorderFactory;
060 import javax.swing.Box;
061 import javax.swing.BoxLayout;
062 import javax.swing.ButtonGroup;
063 import javax.swing.JButton;
064 import javax.swing.JCheckBoxMenuItem;
065 import javax.swing.JFileChooser;
066 import javax.swing.JFrame;
067 import javax.swing.JLabel;
068 import javax.swing.JMenu;
069 import javax.swing.JMenuBar;
070 import javax.swing.JMenuItem;
071 import javax.swing.JOptionPane;
072 import javax.swing.JPanel;
073 import javax.swing.JPopupMenu;
074 import javax.swing.JScrollPane;
075 import javax.swing.JSplitPane;
076 import javax.swing.JToggleButton;
077 import javax.swing.KeyStroke;
078 import javax.swing.UIDefaults;
079 import javax.swing.UIManager;
080 import javax.swing.border.EtchedBorder;
081
082 import org.apache.log4j.Logger;
083
084 import com.languageExplorer.widgets.ScrollableBar;
085
086 import edu.stanford.smi.protege.model.Cls;
087 import edu.stanford.smi.protege.model.Frame;
088 import edu.stanford.smi.protege.model.FrameID;
089 import edu.stanford.smi.protege.model.Instance;
090 import edu.stanford.smi.protege.model.KnowledgeBaseFactory;
091 import edu.stanford.smi.protege.model.Project;
092 import edu.stanford.smi.protege.model.SimpleInstance;
093 import edu.stanford.smi.protege.model.Slot;
094 import edu.stanford.smi.protege.plugin.PluginUtilities;
095 import edu.stanford.smi.protege.resource.LocalizedText;
096 import edu.stanford.smi.protege.resource.ResourceKey;
097 import edu.stanford.smi.protege.resource.Text;
098 import edu.stanford.smi.protege.ui.ClsTreeFinder;
099 import edu.stanford.smi.protege.ui.DisplayUtilities;
100 import edu.stanford.smi.protege.ui.InstanceDisplay;
101 import edu.stanford.smi.protege.ui.ParentChildRoot;
102 import edu.stanford.smi.protege.ui.ProjectManager;
103 import edu.stanford.smi.protege.util.ApplicationProperties;
104 import edu.stanford.smi.protege.util.ComponentUtilities;
105 import edu.stanford.smi.protege.util.Selectable;
106 import edu.stanford.smi.protege.util.URIUtilities;
107 import edu.stanford.smi.protege.widget.AbstractTabWidget;
108 import edu.uchsc.ccp.iaa.IAAException;
109 import edu.uchsc.ccp.knowtator.event.EventHandler;
110 import edu.uchsc.ccp.knowtator.event.FastAnnotateListener;
111 import edu.uchsc.ccp.knowtator.event.FilterChangedEvent;
112 import edu.uchsc.ccp.knowtator.event.FilterChangedListener;
113 import edu.uchsc.ccp.knowtator.event.NotifyTextChangeListener;
114 import edu.uchsc.ccp.knowtator.event.RefreshAnnotationsDisplayListener;
115 import edu.uchsc.ccp.knowtator.event.SelectedAnnotationChangeEvent;
116 import edu.uchsc.ccp.knowtator.event.SelectedAnnotationChangeListener;
117 import edu.uchsc.ccp.knowtator.event.SelectedClsChangeEvent;
118 import edu.uchsc.ccp.knowtator.event.SelectedClsChangeListener;
119 import edu.uchsc.ccp.knowtator.stats.KnowtatorIAA;
120 import edu.uchsc.ccp.knowtator.textsource.TextSource;
121 import edu.uchsc.ccp.knowtator.textsource.TextSourceChangeEvent;
122 import edu.uchsc.ccp.knowtator.textsource.TextSourceSelector;
123 import edu.uchsc.ccp.knowtator.ui.AnnotationInstanceDisplay;
124 import edu.uchsc.ccp.knowtator.ui.AnnotationPicker;
125 import edu.uchsc.ccp.knowtator.ui.AnnotationSchemaInstancesList;
126 import edu.uchsc.ccp.knowtator.ui.AnnotationSchemaTree;
127 import edu.uchsc.ccp.knowtator.ui.KnowtatorTextPane;
128 import edu.uchsc.ccp.knowtator.ui.MentionDisplay;
129 import edu.uchsc.ccp.knowtator.ui.SpanEditPanel;
130 import edu.uchsc.ccp.knowtator.ui.SwingUtils;
131 import edu.uchsc.ccp.knowtator.ui.TextViewer;
132 import edu.uchsc.ccp.knowtator.util.AnnotationCleanup;
133 import edu.uchsc.ccp.knowtator.util.AnnotatorUtil;
134 import edu.uchsc.ccp.knowtator.util.ConsensusAnnotations;
135 import edu.uchsc.ccp.knowtator.util.ConsensusException;
136 import edu.uchsc.ccp.knowtator.util.MergeAnnotations;
137 import edu.uchsc.ccp.knowtator.util.ProjectUtil;
138 import edu.uchsc.ccp.knowtator.wizards.CreateConsensusSetWizard;
139 import edu.uchsc.ccp.knowtator.wizards.FindAnnotateDialog;
140 import edu.uchsc.ccp.knowtator.wizards.IAAWizard;
141 import edu.uchsc.ccp.knowtator.xml.XMLExport;
142 import edu.uchsc.ccp.knowtator.xml.XMLImport;
143
144 /**
145 * Authors: Philip V. Ogren Created: September 2004 Description: This class
146 * implements the AbstractTabWidget - the basic Protege plugin. This is the
147 * central class for the Annotator plugin. Todo: Changes: 8/11/2005 pvo renderer
148 * passed to KB.setClientInformation so that the ComplexSlotMentionValueWidget
149 * can use it. 8/15/2005 pvo added method nextFilterInstance for applying the
150 * "next" select annotation filter. This method should maybe be moved to
151 * ProjectSettings class.
152 */
153
154 public class Knowtator extends AbstractTabWidget implements
155 edu.uchsc.ccp.knowtator.textsource.TextSourceChangeListener, java.awt.event.ActionListener,
156 SelectedAnnotationChangeListener, RefreshAnnotationsDisplayListener, FastAnnotateListener,
157 FilterChangedListener, NotifyTextChangeListener {
158
159 public void filterChanged(FilterChangedEvent event) {
160 filterSelectionLabel.setText("Filter: " + event.getNewFilter().getBrowserText());
161 if (manager.isConsensusMode()) {
162 textViewerPanel.add(consensusModePanel, new GridBagConstraints(0, 1, 1, 1, 0, 0,
163 GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
164 consensusSetItem.setSelected(true);
165 } else {
166 textViewerPanel.remove(consensusModePanel);
167 consensusSetItem.setSelected(false);
168 }
169 textViewerPanel.validate();
170 textViewerPanel.repaint();
171
172 }
173
174 private static final long serialVersionUID = 131l;
175
176 /**
177 * This string is used to give a hash key for the AnnotationUtil that will
178 * be passed to the knowledge base as client information that other objects
179 * can access.
180 */
181
182 public static final String KNOWTATOR_MANAGER = "KNOWTATOR_MANAGER";
183
184 public static final String CHANGE_SORT_METHOD = "CHANGE_SORT_METHOD";
185
186 public static final String SELECT_FILTER = "SELECT_FILTER";
187
188 public static final String SELECT_PREVIOUS_ANNOTATION_FILTER = "SELECT_PREVIOUS_ANNOTATION_FILTER";
189
190 public static final String SELECT_NEXT_ANNOTATION_FILTER = "SELECT_NEXT_ANNOTATION_FILTER";
191
192 public static final String SELECT_PREVIOUS_ANNOTATION = "SELECT_PREVIOUS_ANNOTATION";
193
194 public static final String SELECT_NEXT_ANNOTATION = "SELECT_NEXT_ANNOTATION";
195
196 JSplitPane annotationSchemaPane;
197
198 JPanel clsTreePanel;
199
200 JLabel clsTreeLabel;
201
202 AnnotationSchemaTree clsTree;
203
204 ClsTreeFinder clsFinder;
205
206 JPanel instancesPanel;
207
208 JLabel instancesPaneLabel;
209
210 JScrollPane instancesPane;
211
212 AnnotationSchemaInstancesList instancesList;
213
214 JPanel textViewerPanel;
215
216 JLabel selectedAnnotationLabel;
217
218 JButton deleteAnnotationButton;
219
220 JButton copyAnnotationButton;
221
222 SpanEditPanel spanEditPanel;
223
224 JLabel filterSelectionLabel;
225
226 JButton prevFilterButton;
227
228 JButton selectAnnotationFilterButton;
229
230 JButton nextFilterButton;
231
232 JButton nextAnnotationButton;
233
234 JButton previousAnnotationButton;
235
236 JPanel fastAnnotatePanel;
237
238 JLabel fastAnnotateLabel;
239
240 JButton fastAnnotateSelectButton;
241
242 JButton fastAnnotateQuitButton;
243
244 JPanel consensusModePanel;
245
246 JLabel consensusModeLabel;
247
248 JButton consensusModeCreateButton;
249
250 JButton consensusModeSelectButton;
251
252 JButton consensusModeRestartButton;
253
254 JButton consensusModeConsolidateButton;
255
256 JButton consensusModeQuitButton;
257
258 JLabel consensusModeProgressLabel;
259
260 Selectable lastSelected;
261
262 JPopupMenu popupMenu;
263
264 TextSourceSelector textSourceSelector;
265
266 KnowtatorTextPane textPane;
267
268 TextViewer textViewer;
269
270 JLabel notifyLabel;
271
272 InstanceDisplay textSourceInstanceDisplay;
273
274 // AnnotationInstancesPanel annotationInstancesPanel;
275 AnnotationInstanceDisplay instanceDisplay;
276
277 MentionDisplay mentionDisplay;
278
279 Instance textSourceInstance;
280
281 JMenuItem saveAsMenuItem;
282
283 JMenuItem newProjectMenuItem;
284
285 JMenu knowtatorMenu;
286
287 JMenuItem configureMenuItem;
288
289 JCheckBoxMenuItem fastAnnotateItem;
290
291 JMenuItem findAnnotateMenuItem;
292
293 JMenuItem exportToXMLMenuItem;
294
295 JMenuItem importFromXMLMenuItem;
296
297 JMenuItem annotationRemovalMenuItem;
298
299 JCheckBoxMenuItem showInstancesMenuItem;
300
301 JMenuItem mergeAnnotationsItem;
302
303 JMenuItem batchAnnotatorChangeItem;
304
305 JMenuItem batchAnnotationSetChangeItem;
306
307 JMenuItem iaaItem;
308
309 JMenuItem sortSelectionMenuItem;
310
311 JCheckBoxMenuItem consensusSetItem;
312
313 KnowtatorProjectUtil kpu;
314
315 KnowtatorManager manager;
316
317 AnnotationUtil annotationUtil;
318
319 TextSourceUtil textSourceUtil;
320
321 SpanUtil spanUtil;
322
323 FilterUtil filterUtil;
324
325 MentionUtil mentionUtil;
326
327 DisplayColors displayColors;
328
329 BrowserTextUtil browserTextUtil;
330
331 FindAnnotateDialog findAnnotateDialog;
332
333 Instance defaultAnnotatorInstance;
334
335 boolean showInstances = false;
336
337 Comparator<SimpleInstance> alphabeticalComparator;
338
339 Comparator<SimpleInstance> spanComparator;
340
341 MouseListener instancesListMouseListener;
342
343 JFrame protegeFrame;
344
345 Logger logger = Logger.getLogger(Knowtator.class);
346
347 /**
348 * Map containing the toggle buttons that are displayed in the fast annotate
349 * tool bar.
350 */
351 Map<FrameID, JToggleButton> fastAnnotateButtonMap = new HashMap<FrameID, JToggleButton>();
352
353 /**
354 * The button group associated with the toggle buttons on the fast annotate
355 * tool bar. This button group assures that only one is selected at a time.
356 */
357 ButtonGroup fastAnnotateButtonGroup = new ButtonGroup();
358
359 /**
360 * The component that provides the scrolling for the fast annotate tool bar.
361 */
362 ScrollableBar fastAnnotateScrollableBar = null;
363
364 // startup code
365 public void initialize() {
366 try {
367 logger.debug("Plugins directory located at: " + PluginUtilities.getPluginsDirectory().getPath());
368
369 setUIClassLoader();
370
371 File projectFile = new File(getProject().getProjectURI());
372
373 if (KnowtatorProjectUtil.getKnowtatorSupportClassesVersion(getKnowledgeBase()).equals(KnowtatorProjectUtil.UNVERSIONED)) {
374 int result = JOptionPane.showConfirmDialog(this, "Adding Knowtator to project.\n" +
375 "Please select 'Yes' or 'No' from the following dialog\n" +
376 "then re-open your project. To cancel click 'Cancel'.", "Confirm Knowtator", JOptionPane.OK_CANCEL_OPTION);
377 if(result == JOptionPane.OK_OPTION) {
378 if(ProjectManager.getProjectManager().closeProjectRequest()) {
379
380 Project project = ProjectUtil.openProject(projectFile.getPath());
381 try {
382 KnowtatorProjectUtil.updateKnowtatorProject(project);
383 URI uri = project.getProjectURI();
384 ProjectManager.getProjectManager().loadProject(uri);
385 return;
386 } catch (IOException ioe) {
387 JOptionPane.showMessageDialog(
388 this,
389 "Knowtator experienced difficulty loading the correct support classes.\n"
390 + "Knowtator thinks that it is installed at: "
391 + PluginUtilities.getPluginsDirectory().getPath()
392 + "\n"
393 + "Please verify that the file edu.uchsc.ccp.knowtator"
394 + File.separator
395 + "knowtator.pprj exists there.\n"
396 + "If so, please report this bug along with the stack trace written to the console. Thanks.");
397 ioe.printStackTrace();
398 }
399 }
400 }
401 JOptionPane.showMessageDialog(this, "Knowtator was not added to your project.\n" +
402 "Please de-select Knowtator from the list of Tab Widgets");
403 return;
404 } else if(!KnowtatorProjectUtil.isKnowtatorSupportClassesCurrent(getKnowledgeBase())) {
405 int result = JOptionPane.showConfirmDialog(this, "You are opening an annotation project created\n" +
406 "by an older version of Knowtator. Opening\n" +
407 "this project requires updating Knowtator support\n" +
408 "files. If you proceed with the update, then you\n" +
409 "not open this project in the older version of Knowtator.\n" +
410 "To proceed with the update, please select 'OK' below and\n " +
411 "select 'Yes' or 'No' from the following dialog" +
412 "then re-open your project. To cancel click 'Cancel'.", "Proceed with Knowtator Update?", JOptionPane.OK_CANCEL_OPTION);
413 if(result == JOptionPane.OK_OPTION) {
414 if(ProjectManager.getProjectManager().closeProjectRequest()) {
415
416 Project project = ProjectUtil.openProject(projectFile.getPath());
417 try {
418 KnowtatorProjectUtil.updateKnowtatorProject(project);
419 return;
420 } catch (IOException ioe) {
421 JOptionPane.showMessageDialog(
422 this,
423 "Knowtator experienced difficulty loading the correct support classes.\n"
424 + "Knowtator thinks that it is installed at: "
425 + PluginUtilities.getPluginsDirectory().getPath()
426 + "\n"
427 + "Please verify that the file edu.uchsc.ccp.knowtator"
428 + File.separator
429 + "knowtator.pprj exists there.\n"
430 + "If so, please report this bug along with the stack trace written to the console. Thanks.");
431 ioe.printStackTrace();
432 }
433 }
434 }
435 JOptionPane.showMessageDialog(this, "Knowtator was not updated.");
436 return;
437
438 }
439
440
441
442 kpu = new KnowtatorProjectUtil(getKnowledgeBase(), this);
443
444 manager = new KnowtatorManager(kpu);
445 getKnowledgeBase().setClientInformation(KNOWTATOR_MANAGER, manager);
446
447 annotationUtil = manager.getAnnotationUtil();
448 textSourceUtil = manager.getTextSourceUtil();
449 mentionUtil = manager.getMentionUtil();
450 filterUtil = manager.getFilterUtil();
451 displayColors = manager.getDisplayColors();
452 browserTextUtil = manager.getBrowserTextUtil();
453 spanUtil = manager.getSpanUtil();
454
455 initMenu();
456
457 // ((JFrame) SwingUtilities.getRoot(this)).setTitle("Knowtator");
458 showInstances = ProjectSettings.getShowInstances(getProject());
459
460 // initialize the tab text
461 setLabel("Knowtator");
462
463 // set the icon for the tab
464 setIcon(ComponentUtilities.loadImageIcon(Knowtator.class, "/edu/uchsc/ccp/knowtator/images/annotate.gif"));
465
466 // setIcon(ComponentUtilities.loadImageIcon(
467 // Knowtator.class,
468 // "/edu/uchsc/ccp/knowtator/images/nerd.jpg"));
469
470 initializeFastAnnotatePanel();
471 initializeConsensusModePanel();
472
473 popupMenu = new JPopupMenu();
474 List<Cls> rootClses = manager.getRootClses();
475 clsTree = new AnnotationSchemaTree(manager, null, new ParentChildRoot(rootClses));
476 clsFinder = new ClsTreeFinder(manager.getKnowledgeBase(), clsTree);
477
478 instancesList = new AnnotationSchemaInstancesList(manager);
479
480 textPane = new KnowtatorTextPane(manager);
481 manager.setTextPane(textPane);
482 textViewer = new TextViewer(textPane, manager);
483 manager.setTextViewer(textViewer);
484 textSourceUtil.addTextSourceChangeListener(textViewer);
485 textSourceUtil.addTextSourceChangeListener(this); // I had to
486 // change the order of this so that the handling of the text source
487 // change would be in
488 // the right order.
489
490 textSourceUtil.addTextSourceChangeListener(spanUtil);
491 textSourceUtil.addTextSourceChangeListener(manager);
492
493 textSourceSelector = new TextSourceSelector(getProject(), textSourceUtil, getMainWindowToolBar(), this);
494
495 textSourceInstanceDisplay = new InstanceDisplay(getProject(), false, false);
496
497 alphabeticalComparator = browserTextUtil.comparator();
498 spanComparator = spanUtil.comparator(alphabeticalComparator);
499
500 manager.setAnnotationComparator(spanComparator);
501
502 instanceDisplay = new AnnotationInstanceDisplay(kpu, getProject(), false, false);
503 mentionDisplay = new MentionDisplay(manager, getProject());
504
505 clsTreePanel = new JPanel(new GridBagLayout());
506 clsTreeLabel = new JLabel("annotation schema");
507 clsTreePanel.add(clsTreeLabel, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST,
508 GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
509 clsTreePanel.add(new JScrollPane(clsTree), new GridBagConstraints(0, 1, 1, 1, .5, .5,
510 GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
511 clsTreePanel.add(clsFinder, new GridBagConstraints(0, 2, 1, 1, 1.0, 0, GridBagConstraints.CENTER,
512 GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
513
514 instancesPanel = new JPanel(new GridBagLayout());
515 instancesPaneLabel = new JLabel();
516
517 EventHandler.getInstance().addSelectedClsChangeListener(new SelectedClsChangeListener() {
518 public void clsSelectionChanged(SelectedClsChangeEvent scce) {
519 Cls selectedCls = manager.getSelectedCls();
520 if (ProjectSettings.getShowInstances(getProject())) {
521 instancesPaneLabel.setText("Instances of '" + selectedCls.getBrowserText() + "'");
522 }
523 }
524 });
525
526 instancesPane = new JScrollPane(instancesList);
527 instancesPanel.add(instancesPaneLabel, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST,
528 GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
529 instancesPanel.add(instancesPane, new GridBagConstraints(0, 1, 1, 1, .5, .5, GridBagConstraints.CENTER,
530 GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
531
532 filterSelectionLabel = new JLabel("Filter: " + manager.getSelectedFilter().getBrowserText());
533 prevFilterButton = new JButton(ComponentUtilities.loadImageIcon(Knowtator.class,
534 "/edu/uchsc/ccp/knowtator/images/prev.gif"));
535 prevFilterButton.setActionCommand(Knowtator.SELECT_PREVIOUS_ANNOTATION_FILTER);
536 prevFilterButton.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
537 prevFilterButton.setToolTipText("select previous annotation filter");
538 prevFilterButton.setBorder(null);
539 prevFilterButton.addActionListener(this);
540
541 selectAnnotationFilterButton = new JButton(ComponentUtilities.loadImageIcon(Knowtator.class,
542 "/edu/uchsc/ccp/knowtator/images/History24.gif"));
543 selectAnnotationFilterButton.setActionCommand(Knowtator.SELECT_FILTER);
544 selectAnnotationFilterButton.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
545 selectAnnotationFilterButton.setToolTipText("Select from the list of active annotation filters");
546 selectAnnotationFilterButton.setBorder(null);
547 selectAnnotationFilterButton.addActionListener(this);
548
549 nextFilterButton = new JButton(ComponentUtilities.loadImageIcon(Knowtator.class,
550 "/edu/uchsc/ccp/knowtator/images/next.gif"));
551 nextFilterButton.setActionCommand(Knowtator.SELECT_NEXT_ANNOTATION_FILTER);
552 nextFilterButton.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
553 nextFilterButton.setToolTipText("select next annotation filter");
554 nextFilterButton.setBorder(null);
555 nextFilterButton.addActionListener(this);
556
557 nextAnnotationButton = new JButton(ComponentUtilities.loadImageIcon(Knowtator.class,
558 "/edu/uchsc/ccp/knowtator/images/next.gif"));
559 nextAnnotationButton.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
560 nextAnnotationButton.setToolTipText("select next annotation");
561 nextAnnotationButton.setBorder(null);
562 nextAnnotationButton.addActionListener(new ActionListener() {
563 public void actionPerformed(ActionEvent event) {
564 manager.selectNextAnnotation();
565 }
566 });
567 previousAnnotationButton = new JButton(ComponentUtilities.loadImageIcon(Knowtator.class,
568 "/edu/uchsc/ccp/knowtator/images/prev.gif"));
569 previousAnnotationButton.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
570 previousAnnotationButton.setToolTipText("select previous annotation");
571 previousAnnotationButton.setBorder(null);
572 previousAnnotationButton.addActionListener(new ActionListener() {
573 public void actionPerformed(ActionEvent event) {
574 manager.selectPreviousAnnotation();
575 }
576 });
577
578 getMainWindowToolBar().addSeparator();
579 getMainWindowToolBar().add(filterSelectionLabel);
580 getMainWindowToolBar().addSeparator();
581 getMainWindowToolBar().add(prevFilterButton);
582 getMainWindowToolBar().addSeparator();
583 getMainWindowToolBar().add(selectAnnotationFilterButton);
584 getMainWindowToolBar().addSeparator();
585 getMainWindowToolBar().add(nextFilterButton);
586 getMainWindowToolBar().addSeparator();
587 getMainWindowToolBar().add(previousAnnotationButton);
588 getMainWindowToolBar().addSeparator();
589 getMainWindowToolBar().add(nextAnnotationButton);
590
591 // Layout and add components
592 annotationSchemaPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, clsTreePanel, instancesPanel);
593 annotationSchemaPane.setDividerLocation(400);
594
595 textViewerPanel = new JPanel(new GridBagLayout());
596 textViewerPanel.add(textViewer.getContentPane(), new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0,
597 GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 4, 4));
598
599 // JSplitPane rightPane1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
600 // annotationInstancesPanel,
601 // mentionDisplay);
602 // rightPane1.setDividerLocation(350);
603 JSplitPane rightPane2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, instanceDisplay,
604 textSourceInstanceDisplay);
605 rightPane2.setDividerLocation(400);
606 rightPane2.setOneTouchExpandable(true);
607
608 selectedAnnotationLabel = new JLabel("no annotation selected");
609 deleteAnnotationButton = new JButton("DELETE");
610 deleteAnnotationButton.setToolTipText("Delete this annotation");
611 deleteAnnotationButton.addActionListener(new ActionListener() {
612 public void actionPerformed(ActionEvent event) {
613 manager.deleteSelectedAnnotation();
614 }
615 });
616 copyAnnotationButton = new JButton("COPY");
617 copyAnnotationButton.setToolTipText("Copy this annotation");
618 copyAnnotationButton.addActionListener(new ActionListener() {
619 public void actionPerformed(ActionEvent event) {
620 manager.duplicateSelectedAnnotation();
621 }
622 });
623
624 selectedAnnotationLabel.setFont(getFont().deriveFont(16f).deriveFont(Font.BOLD));
625 spanEditPanel = new SpanEditPanel(manager, instanceDisplay);
626
627 JPanel upperRightPanel = new JPanel(new GridBagLayout());
628 upperRightPanel.add(deleteAnnotationButton, new GridBagConstraints(0, 0, 1, 1, 0, 0,
629 GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
630 upperRightPanel.add(selectedAnnotationLabel, new GridBagConstraints(2, 0, 1, 1, 1.0, 0,
631 GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 4, 4));
632 upperRightPanel.add(spanEditPanel, new GridBagConstraints(0, 1, 3, 1, 0, 0, GridBagConstraints.WEST,
633 GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
634 upperRightPanel.add(mentionDisplay, new GridBagConstraints(0, 2, 3, 1, 1.0, 1.0, GridBagConstraints.WEST,
635 GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 4, 4));
636 JSplitPane rightPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, upperRightPanel, rightPane2);
637 rightPane.setDividerLocation(400);
638 rightPane.setOneTouchExpandable(true);
639
640 JSplitPane schemaAndTextViewerSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, annotationSchemaPane,
641 textViewerPanel);
642 schemaAndTextViewerSplitPane.setDividerLocation(200);
643 schemaAndTextViewerSplitPane.setOneTouchExpandable(true);
644
645 JSplitPane pane2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, schemaAndTextViewerSplitPane, rightPane);
646 pane2.setDividerLocation(800);
647
648 setLayout(new BorderLayout());
649 add(pane2, BorderLayout.CENTER);
650
651 showInstancesPane(showInstances);
652 notifyLabel = new JLabel();
653
654 textSourceUtil.init();
655
656 EventHandler.getInstance().addSelectedAnnotationChangeListener(this);
657 EventHandler.getInstance().addRefreshAnnotationsDisplayListener(this);
658 EventHandler.getInstance().addFastAnnotateListener(this);
659 EventHandler.getInstance().addFilterChangedListener(this);
660 EventHandler.getInstance().addNotifyTextChangeListener(this);
661
662 try {
663 manager.setSelectedFilter(manager.getSelectedFilter());
664 } catch (Exception e) {
665 e.printStackTrace();
666 }
667
668 manager.updateCurrentAnnotations();
669
670 } catch (Throwable t) {
671 t.printStackTrace();
672 }
673
674 }
675
676 public void notifyTextChanged(String notifyText) {
677 if (notifyText == null || notifyText.trim().equals(""))
678 remove(notifyLabel);
679 else {
680 add(notifyLabel, BorderLayout.SOUTH);
681 notifyLabel.setText(notifyText);
682 }
683 }
684
685 private void initializeConsensusModePanel() {
686 consensusModePanel = new JPanel(new GridBagLayout());
687 consensusModeLabel = new JLabel("consensus mode");
688 Font labelFont = consensusModeLabel.getFont();
689 consensusModeLabel.setFont(labelFont.deriveFont((float) (labelFont.getSize() + 8)));
690
691 consensusModeCreateButton = new JButton("create");
692 consensusModeCreateButton.setToolTipText("create a new consensus set to work on");
693 consensusModeCreateButton.addActionListener(new ActionListener() {
694 public void actionPerformed(ActionEvent event) {
695 logger.debug("");
696 try {
697 CreateConsensusSetWizard wizard = new CreateConsensusSetWizard(getProtegeFrame(), manager);
698 wizard.setVisible(true);
699 if (wizard.createConsensusSet()) {
700 ConsensusAnnotations.createConsensusAnnotations(manager, wizard.getFilter(), wizard
701 .getConsensusSetName(), wizard.getTextSources());
702 textSourceUtil.setCurrentTextSource(textSourceUtil.getCurrentTextSource());
703 }
704 } catch (ConsensusException ce) {
705 JOptionPane.showMessageDialog(Knowtator.this, ce.getMessage(), "Consensus Set Error",
706 JOptionPane.ERROR_MESSAGE);
707 ce.printStackTrace();
708 }
709 }
710 });
711
712 consensusModeSelectButton = new JButton("select");
713 consensusModeSelectButton.setToolTipText("select consensus set to work on");
714 consensusModeSelectButton.addActionListener(new ActionListener() {
715 public void actionPerformed(ActionEvent event) {
716 List<Cls> clses = new ArrayList<Cls>();
717 clses.add(kpu.getConsensusSetCls());
718 Instance instance = DisplayUtilities.pickInstance(Knowtator.this, clses, "Select consensus set");
719 if (instance != null) {
720 // manager.setSelectedFilter((SimpleInstance) instance);
721 }
722 }
723 });
724 consensusModeRestartButton = new JButton("restart");
725 consensusModeRestartButton.setEnabled(true);
726 consensusModeRestartButton.setToolTipText("start over with consensus work on this text source");
727 consensusModeRestartButton.addActionListener(new ActionListener() {
728 public void actionPerformed(ActionEvent event) {
729 try {
730 int option = JOptionPane.showConfirmDialog(Knowtator.this,
731 "To start over with consensus work on this text source, please click 'OK'.\n"
732 + "The annotations in the consensus set for this text source will be deleted.\n"
733 + "The original annotations that were used to create the consensus set will be\n"
734 + "copied into the consensus set again.",
735 "restart consensus work on this text source", JOptionPane.OK_CANCEL_OPTION);
736
737 if (option != JOptionPane.OK_OPTION)
738 return;
739
740 manager.restartConsensusMode();
741 } catch (ConsensusException ce) {
742 JOptionPane.showMessageDialog(Knowtator.this, ce.getMessage(), "Consensus Set Error",
743 JOptionPane.ERROR_MESSAGE);
744 ce.printStackTrace();
745 }
746 }
747 });
748
749 consensusModeConsolidateButton = new JButton("consolidate");
750 consensusModeConsolidateButton.setEnabled(false);
751 consensusModeConsolidateButton
752 .setToolTipText("delete the currently selected annotation after selecting the annotation it should be consolidated with");
753 consensusModeConsolidateButton.addActionListener(new ActionListener() {
754 public void actionPerformed(ActionEvent event) {
755 List<SimpleInstance> annotations = new ArrayList<SimpleInstance>(manager
756 .getCurrentFilteredAnnotations());
757 annotations.remove(manager.getSelectedAnnotation());
758 List<SimpleInstance> selection = AnnotationPicker.pickAnnotationsFromCollection(Knowtator.this,
759 manager, annotations, "select the preferred annotation", false);
760 if (selection != null && selection.size() == 1) {
761 SimpleInstance deleteAnnotation = manager.getSelectedAnnotation();
762 SimpleInstance consolidateAnnotation = selection.get(0);
763 manager.consolidateAnnotation(deleteAnnotation, consolidateAnnotation);
764 }
765 }
766 });
767
768 consensusModeQuitButton = new JButton("quit");
769 consensusModeQuitButton.setToolTipText("quit consensus mode");
770 consensusModeQuitButton.addActionListener(new ActionListener() {
771 public void actionPerformed(ActionEvent event) {
772 stopConsensusMode();
773 }
774 });
775
776 consensusModeProgressLabel = new JLabel("");
777
778 consensusModePanel.add(consensusModeLabel, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST,
779 GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
780 consensusModePanel.add(consensusModeCreateButton, new GridBagConstraints(1, 0, 1, 1, 0, 0,
781 GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
782 consensusModePanel.add(consensusModeSelectButton, new GridBagConstraints(1, 0, 1, 1, 0, 0,
783 GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
784 consensusModePanel.add(consensusModeRestartButton, new GridBagConstraints(2, 0, 1, 1, 0, 0,
785 GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
786 consensusModePanel.add(consensusModeQuitButton, new GridBagConstraints(3, 0, 1, 1, 0, 0,
787 GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
788 consensusModePanel.add(consensusModeConsolidateButton, new GridBagConstraints(4, 0, 1, 1, 0, 0,
789 GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
790 consensusModePanel.add(consensusModeProgressLabel, new GridBagConstraints(0, 1, 5, 1, 0, 0,
791 GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 4, 4));
792 }
793
794 // use class selection mode used by find/annotate
795 private void initializeFastAnnotatePanel() {
796 fastAnnotatePanel = new JPanel(new GridBagLayout());
797 fastAnnotateLabel = new JLabel("fast annotate ");
798 fastAnnotateSelectButton = new JButton("select class");
799 fastAnnotateSelectButton.setToolTipText("click to change fast annotate class");
800 fastAnnotateQuitButton = new JButton("quit");
801 fastAnnotateQuitButton.setToolTipText("click to quit fast annotate mode");
802
803 Font labelFont = fastAnnotateLabel.getFont();
804 fastAnnotateLabel.setFont(labelFont.deriveFont((float) (labelFont.getSize() + 8)));
805 fastAnnotateSelectButton.addActionListener(new ActionListener() {
806 public void actionPerformed(ActionEvent event) {
807 List<Cls> rootClses = manager.getRootClses();
808 Instance instance = DisplayUtilities.pickCls(Knowtator.this, getKnowledgeBase(), rootClses,
809 "Select fast annotation class");
810 if (instance != null) {
811 Cls fastAnnotateCls = (Cls) instance;
812 manager.setFastAnnotateFrame(fastAnnotateCls);
813 }
814 }
815 });
816 fastAnnotateQuitButton.addActionListener(new ActionListener() {
817 public void actionPerformed(ActionEvent event) {
818 manager.quitFastAnnotate();
819 }
820 });
821
822 fastAnnotatePanel.setLayout(new BoxLayout(fastAnnotatePanel, BoxLayout.X_AXIS));
823 fastAnnotatePanel.add(Box.createRigidArea(new Dimension(5, 30)));
824 fastAnnotatePanel.add(fastAnnotateLabel);
825 fastAnnotatePanel.add(Box.createHorizontalStrut(10));
826 fastAnnotatePanel.add(fastAnnotateQuitButton);
827 fastAnnotatePanel.add(Box.createHorizontalStrut(5));
828
829 fastAnnotateScrollableBar = new ScrollableBar(fastAnnotatePanel);
830 List<Cls> rootClses = manager.getRootClses();
831 for (Cls rootCls : rootClses) {
832 // Initialize the toolbar with the root classes
833 fastAnnotateAddCls(rootCls);
834 }
835 }
836
837 public void fastAnnotateStart() {
838 add(fastAnnotateScrollableBar, BorderLayout.NORTH);
839 validate();
840 repaint();
841 fastAnnotateItem.setSelected(true);
842
843 // If no buttons exist on the toolbar, allow the user to select a class,
844 // add
845 // the button for the class, and select it
846 Frame fastAnnotateFrame = manager.getFastAnnotateFrame();
847 if (fastAnnotateFrame == null || fastAnnotateButtonMap.isEmpty()) {
848 List<Cls> rootClses = manager.getRootClses();
849 Instance instance = DisplayUtilities.pickCls(Knowtator.this, getKnowledgeBase(), rootClses,
850 "Select fast annotation class");
851 if (instance != null) {
852 Cls fastAnnotateCls = (Cls) instance;
853 manager.setFastAnnotateFrame(fastAnnotateCls);
854 } else {
855 // User canceled dialog
856 manager.quitFastAnnotate();
857 fastAnnotateItem.setSelected(false);
858 }
859 }
860
861 if (!isFastAnnotateButtonSelected()) {
862 selectFirstFastAnnotateButton();
863 }
864 }
865
866 public void fastAnnotateQuit() {
867 remove(fastAnnotateScrollableBar);
868 fastAnnotateItem.setSelected(false);
869 validate();
870 repaint();
871 }
872
873 public void fastAnnotateClsChange() {
874 Frame fastAnnotateFrame = manager.getFastAnnotateFrame();
875 if (fastAnnotateFrame != null) {
876 JToggleButton toggleButton = fastAnnotateButtonMap.get(fastAnnotateFrame.getFrameID());
877 if (toggleButton != null) {
878 toggleButton.setSelected(true);
879 }
880 }
881 }
882
883 public void fastAnnotateAddCls(final Frame frame) {
884 if (!fastAnnotateButtonMap.containsKey(frame.getFrameID())) {
885 final JToggleButton newButton = new JToggleButton(frame.getBrowserText());
886 newButton.setIcon(displayColors.getIcon(displayColors.getColor(frame)));
887 newButton.addActionListener(new ActionListener() {
888 public void actionPerformed(ActionEvent evt) {
889 manager.setFastAnnotateFrame(frame);
890 }
891 });
892
893 newButton.addMouseListener(new MouseAdapter() {
894 public void mousePressed(MouseEvent evt) {
895 invokeRemoveMenu(evt);
896 }
897
898 public void mouseReleased(MouseEvent evt) {
899 invokeRemoveMenu(evt);
900 }
901
902 private void invokeRemoveMenu(MouseEvent evt) {
903 if (evt.isPopupTrigger()) {
904 AbstractAction removeFastAnnotateButtonAction = new AbstractAction("Remove") {
905 public void actionPerformed(ActionEvent evt) {
906 fastAnnotateRemoveCls(frame);
907 }
908 };
909 JPopupMenu fastAnnotatePopupMenu = new JPopupMenu();
910 fastAnnotatePopupMenu.add(removeFastAnnotateButtonAction);
911 fastAnnotatePopupMenu.show(newButton, evt.getX(), evt.getY());
912 }
913 }
914 });
915
916 fastAnnotateButtonGroup.add(newButton);
917 fastAnnotateButtonMap.put(frame.getFrameID(), newButton);
918 fastAnnotatePanel.add(newButton, 3);
919
920 fastAnnotatePanel.add(Box.createHorizontalStrut(3), 4);
921 manager.setFastAnnotateFrame(frame);
922 fastAnnotatePanel.validate();
923 fastAnnotatePanel.repaint();
924 fastAnnotateScrollableBar.validate();
925 fastAnnotateScrollableBar.repaint();
926 }
927 }
928
929 public void fastAnnotateRemoveCls(Frame frame) {
930 JToggleButton button = fastAnnotateButtonMap.get(frame.getFrameID());
931 if (button != null) {
932 boolean removedButtonIsSelected = button.isSelected();
933 int index = SwingUtils.indexOfComponent(fastAnnotatePanel, button);
934 fastAnnotatePanel.remove(button);
935
936 if (index != -1) {
937 // Remove the padding (strut) between components
938 fastAnnotatePanel.remove(index);
939 }
940
941 fastAnnotatePanel.validate();
942 fastAnnotatePanel.repaint();
943 fastAnnotateButtonMap.remove(frame.getFrameID());
944 if (fastAnnotateButtonMap.isEmpty()) {
945 manager.quitFastAnnotate();
946 }
947
948 if (removedButtonIsSelected) {
949 selectFirstFastAnnotateButton();
950 }
951
952 fastAnnotateScrollableBar.validate();
953 fastAnnotateScrollableBar.repaint();
954 }
955 }
956
957 /**
958 * Finds out if one of the fast annotate buttons is selected. This is used
959 * to automatically select a button when starting fast annotate mode.
960 *
961 * @return True if and only if one of the toggle buttons in the fast
962 * annotate button map is selected. Returns false if no buttons are
963 * selected.
964 */
965 private boolean isFastAnnotateButtonSelected() {
966 for (JToggleButton fastAnnotateButton : fastAnnotateButtonMap.values()) {
967 if (fastAnnotateButton.isSelected()) {
968 return true;
969 }
970 }
971 return false;
972 }
973
974 /**
975 * Automatically selects the first button found in the toggle button map.
976 * There is no guaranteed order as to which button will be selected.
977 */
978 private void selectFirstFastAnnotateButton() {
979 Collection<JToggleButton> fastAnnotateButtons = fastAnnotateButtonMap.values();
980 for (JToggleButton togButton : fastAnnotateButtons) {
981 togButton.setSelected(true);
982 break;
983 }
984 }
985
986 public void annotationSelectionChanged(SelectedAnnotationChangeEvent sace) {
987 SimpleInstance selectedAnnotation = sace.getSelectedAnnotation();
988 if (selectedAnnotation == null) {
989 selectedAnnotationLabel.setText("no annotation selected");
990 consensusModeConsolidateButton.setEnabled(false);
991 } else {
992 selectedAnnotationLabel.setText(browserTextUtil.getBrowserText(selectedAnnotation, 60));
993 selectedAnnotationLabel.setIcon(displayColors.getIcon(displayColors.getColor(selectedAnnotation)));
994 if (manager.isConsensusMode())
995 consensusModeConsolidateButton.setEnabled(true);
996 }
997 }
998
999 public void refreshAnnotationsDisplay(boolean scrollToSelection) {
1000 SimpleInstance selectedAnnotation = manager.getSelectedAnnotation();
1001 if (selectedAnnotation == null) {
1002 selectedAnnotationLabel.setText("no annotation selected");
1003 selectedAnnotationLabel.setIcon(null);
1004 } else {
1005 selectedAnnotationLabel.setText(browserTextUtil.getBrowserText(selectedAnnotation, 60));
1006 selectedAnnotationLabel.setIcon(displayColors.getIcon(displayColors.getColor(selectedAnnotation)));
1007 }
1008 if (manager.isConsensusMode()) {
1009 int progress = manager.getConsensusModeProgress();
1010 int numberOfAnnotations = manager.getCurrentFilteredAnnotations().size();
1011 if (progress == numberOfAnnotations)
1012 consensusModeProgressLabel.setText("progress: complete " + progress + "/" + numberOfAnnotations);
1013 else
1014 consensusModeProgressLabel.setText("progress: " + progress + "/" + numberOfAnnotations);
1015 }
1016 }
1017
1018 private void initFindAnnotateDialog() {
1019 findAnnotateDialog = new FindAnnotateDialog(getProject(), getProtegeFrame(), textPane, manager);
1020 textSourceUtil.addTextSourceChangeListener(findAnnotateDialog);
1021 textViewer.getTextPane().addCaretListener(findAnnotateDialog);
1022 findAnnotateDialog.textSourceChanged(new TextSourceChangeEvent(textSourceUtil.getCurrentTextSource()));
1023 }
1024
1025 private JFrame getProtegeFrame() {
1026 if (protegeFrame == null) {
1027 Container container = this.getParent();
1028 if (container == null)
1029 return null;
1030 while (container != null && !(container instanceof JFrame))
1031 container = container.getParent();
1032 protegeFrame = (JFrame) container;
1033 }
1034 // protegeFrame.setIconImage(ComponentUtilities.loadImageIcon(Knowtator.
1035 // class,
1036 // "/edu/uchsc/ccp/knowtator/images/nerd.jpg").getImage());
1037
1038 return protegeFrame;
1039 }
1040
1041 private void showInstancesPane(boolean show) {
1042 if (show) {
1043 annotationSchemaPane.setDividerLocation(350);
1044 } else {
1045 annotationSchemaPane.setDividerLocation(2000);
1046 }
1047 ProjectSettings.setShowInstances(getProject(), show);
1048 showInstancesMenuItem.setSelected(show);
1049 showInstances = show;
1050 }
1051
1052 private void updateProjectMenuBar() {
1053 JMenuBar pmb = ProjectManager.getProjectManager().getCurrentProjectMenuBar();
1054 Component[] components = pmb.getComponents();
1055 for (Component component : components) {
1056 if (component instanceof JMenu) {
1057 JMenu menu = (JMenu) component;
1058 System.out.println(menu.getText());
1059 String localizedText = LocalizedText.getText(ResourceKey.MENUBAR_FILE);
1060 if (localizedText.equals(menu.getText())) {
1061 menu.add(newProjectMenuItem, 0);
1062 components = menu.getMenuComponents();
1063 int i = 0;
1064 for (Component component2 : components) {
1065 if (component2 instanceof JMenuItem) {
1066 JMenuItem jmi = (JMenuItem) component2;
1067 localizedText = LocalizedText.getText(ResourceKey.PROJECT_SAVE_AS);
1068 if (jmi.getText().equals(localizedText)) {
1069 menu.add(saveAsMenuItem, i);
1070 }
1071 }
1072 i++;
1073 }
1074 }
1075 }
1076 }
1077 }
1078
1079 private void initMenu() {
1080 JMenuBar menuBar = getMainWindowMenuBar();
1081
1082 saveAsMenuItem = new JMenuItem("Save Knowtator Project As...");
1083 saveAsMenuItem.addActionListener(new SaveAsAction());
1084 saveAsMenuItem.setMnemonic('v');
1085
1086 newProjectMenuItem = new JMenuItem("New Knowtator Project...");
1087 newProjectMenuItem.addActionListener(new NewProjectAction());
1088 newProjectMenuItem.setMnemonic('k');
1089
1090 updateProjectMenuBar();
1091
1092 knowtatorMenu = new JMenu("Knowtator");
1093 knowtatorMenu.setMnemonic('k');
1094 knowtatorMenu.setFont(UIManager.getFont("MenuBar.font"));
1095 configureMenuItem = new JMenuItem(new ConfigureAction());
1096 fastAnnotateItem = new JCheckBoxMenuItem(new FastAnnotateAction());
1097 findAnnotateMenuItem = new JMenuItem(new FindAnnotateAction());
1098
1099 sortSelectionMenuItem = new JMenuItem("Change annotation sort order");
1100 sortSelectionMenuItem.setEnabled(true);
1101 sortSelectionMenuItem.setActionCommand(CHANGE_SORT_METHOD);
1102 sortSelectionMenuItem.addActionListener(this);
1103 sortSelectionMenuItem.setMnemonic('s');
1104
1105 exportToXMLMenuItem = new JMenuItem(new XMLExportAction());
1106 importFromXMLMenuItem = new JMenuItem(new XMLImportAction());
1107
1108 annotationRemovalMenuItem = new JMenuItem("Remove annotations");
1109 annotationRemovalMenuItem.addActionListener(this);
1110 annotationRemovalMenuItem.setMnemonic('r');
1111
1112 showInstancesMenuItem = new JCheckBoxMenuItem(new ShowInstancesAction());
1113
1114 mergeAnnotationsItem = new JMenuItem("Merge annotations");
1115 mergeAnnotationsItem.addActionListener(this);
1116 mergeAnnotationsItem.setMnemonic('m');
1117
1118 batchAnnotatorChangeItem = new JMenuItem("Reassign annotator value in batch");
1119 batchAnnotatorChangeItem.addActionListener(this);
1120 batchAnnotatorChangeItem.setMnemonic('b');
1121
1122 batchAnnotationSetChangeItem = new JMenuItem("Assign annotation set value in batch");
1123 batchAnnotationSetChangeItem.addActionListener(this);
1124 batchAnnotationSetChangeItem.setMnemonic('b');
1125
1126 iaaItem = new JMenuItem("Calculate IAA");
1127 iaaItem.addActionListener(this);
1128 iaaItem.setMnemonic('c');
1129
1130 consensusSetItem = new JCheckBoxMenuItem("Consensus Mode");
1131 consensusSetItem.addActionListener(this);
1132 consensusSetItem.setMnemonic('o');
1133
1134 knowtatorMenu.add(configureMenuItem);
1135 knowtatorMenu.add(fastAnnotateItem);
1136 knowtatorMenu.add(findAnnotateMenuItem);
1137 knowtatorMenu.add(sortSelectionMenuItem);
1138 knowtatorMenu.add(exportToXMLMenuItem);
1139 knowtatorMenu.add(importFromXMLMenuItem);
1140 knowtatorMenu.add(annotationRemovalMenuItem);
1141 knowtatorMenu.add(showInstancesMenuItem);
1142 knowtatorMenu.add(mergeAnnotationsItem);
1143 knowtatorMenu.add(batchAnnotatorChangeItem);
1144 knowtatorMenu.add(batchAnnotationSetChangeItem);
1145 knowtatorMenu.add(iaaItem);
1146 knowtatorMenu.add(consensusSetItem);
1147 menuBar.add(knowtatorMenu);
1148 }
1149
1150 public static boolean isSuitable(Project project, Collection errors) {
1151 boolean isSuitable = true;
1152 if (project.getLoadingURI() == null) {
1153 isSuitable = false;
1154 errors.add("Knowtator cannot be loaded until project is saved.");
1155 }
1156 return isSuitable;
1157 }
1158
1159 public void textSourceChanged(TextSourceChangeEvent event) {
1160 TextSource currentTextSource = event.getTextSource();
1161 textSourceInstanceDisplay.setInstance(textSourceUtil.getTextSourceInstance(currentTextSource, false));
1162 }
1163
1164 public void selectFilterInstance() {
1165 Collection<SimpleInstance> filterInstances = manager.getActiveFilters();
1166 SimpleInstance selectedFilter = (SimpleInstance) edu.stanford.smi.protege.ui.DisplayUtilities
1167 .pickInstanceFromCollection(this, filterInstances, 0, "Choose an annotation filter");
1168 if (selectedFilter != null) {
1169 try {
1170 manager.setSelectedFilter(selectedFilter);
1171 } catch (ConsensusException ce) {
1172 JOptionPane.showMessageDialog(Knowtator.this, ce.getMessage(), "Consensus Set Error",
1173 JOptionPane.ERROR_MESSAGE);
1174 ce.printStackTrace();
1175 }
1176 }
1177 }
1178
1179 /**
1180 * Action that toggles the fast annotate mode.
1181 *
1182 * @author brantbarney
1183 */
1184 @SuppressWarnings("serial")
1185 class FastAnnotateAction extends AbstractAction {
1186 public FastAnnotateAction() {
1187 super("fast annotate mode");
1188 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit()
1189 .getMenuShortcutKeyMask()));
1190 putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_F));
1191 }
1192
1193 public void actionPerformed(ActionEvent evt) {
1194 if (fastAnnotateItem.isSelected()) {
1195 manager.startFastAnnotate();
1196 } else {
1197 manager.quitFastAnnotate();
1198 }
1199 }
1200 }
1201
1202 /**
1203 * Action used to launch the find/annotate dialog used to search the text
1204 * documents
1205 *
1206 * @author brantbarney
1207 */
1208 @SuppressWarnings("serial")
1209 class FindAnnotateAction extends AbstractAction {
1210 public FindAnnotateAction() {
1211 super("Find/Annotate");
1212 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit()
1213 .getMenuShortcutKeyMask()));
1214 putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_A));
1215 }
1216
1217 public void actionPerformed(ActionEvent evt) {
1218 if (findAnnotateDialog == null) {
1219 initFindAnnotateDialog();
1220 }
1221 findAnnotateDialog.setVisible(true);
1222 }
1223 }
1224
1225 /**
1226 * Action used to launch the Knowtator configuration dialog
1227 *
1228 * @author brantbarney
1229 */
1230 @SuppressWarnings("serial")
1231 class ConfigureAction extends AbstractAction {
1232 public ConfigureAction() {
1233 super("Configure");
1234 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit()
1235 .getMenuShortcutKeyMask()));
1236 putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_C));
1237 }
1238
1239 public void actionPerformed(ActionEvent evt) {
1240 getProject().show(ProjectSettings.getActiveConfiguration(getProject()));
1241 }
1242 }
1243
1244 /**
1245 * UI Action used to start the XML export wizard, exporting the current
1246 * project to XML format
1247 *
1248 * @author brantbarney
1249 */
1250 @SuppressWarnings("serial")
1251 class XMLExportAction extends AbstractAction {
1252 public XMLExportAction() {
1253 super("Export annotations to xml");
1254 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit.getDefaultToolkit()
1255 .getMenuShortcutKeyMask()));
1256 putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_X));
1257 }
1258
1259 public void actionPerformed(ActionEvent evt) {
1260 XMLExport.writeToXML(Knowtator.this, getKnowledgeBase(), kpu, textSourceUtil, annotationUtil, mentionUtil,
1261 filterUtil, getProject());
1262 }
1263 }
1264
1265 /**
1266 * UI Action to start the XML import wizard, to import a project from an XML
1267 * file.
1268 *
1269 * @author brantbarney
1270 */
1271 @SuppressWarnings("serial")
1272 class XMLImportAction extends AbstractAction {
1273 public XMLImportAction() {
1274 super("Import annotations from xml");
1275 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_P, Toolkit.getDefaultToolkit()
1276 .getMenuShortcutKeyMask()));
1277 putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_I));
1278 }
1279
1280 public void actionPerformed(ActionEvent evt) {
1281 XMLImport.readFromXML(Knowtator.this, getKnowledgeBase(), kpu, textSourceUtil, annotationUtil, mentionUtil,
1282 filterUtil, getProject());
1283 }
1284 }
1285
1286 /**
1287 * UI Action that toggles the Show Instances pane
1288 *
1289 * @author brantbarney
1290 */
1291 @SuppressWarnings("serial")
1292 class ShowInstancesAction extends AbstractAction {
1293 public ShowInstancesAction() {
1294 super("Show instances");
1295 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_I, Toolkit.getDefaultToolkit()
1296 .getMenuShortcutKeyMask()));
1297 putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_I));
1298 }
1299
1300 public void actionPerformed(ActionEvent evt) {
1301 showInstancesPane(showInstancesMenuItem.isSelected());
1302 }
1303 }
1304
1305 public void actionPerformed(ActionEvent actionEvent) {
1306 Object source = actionEvent.getSource();
1307 String command = actionEvent.getActionCommand();
1308
1309 if (source == annotationRemovalMenuItem) {
1310 AnnotationCleanup.cleanup(this, getKnowledgeBase(), kpu, textSourceUtil, annotationUtil, mentionUtil,
1311 filterUtil, getProject());
1312 } else if (source == mergeAnnotationsItem) {
1313 MergeAnnotations.mergeAnnotations(this, getProject(), textSourceUtil);
1314 manager.updateCurrentAnnotations();
1315 } else if (source == batchAnnotatorChangeItem) {
1316 AnnotatorUtil.batchAnnotatorChange(this, kpu, annotationUtil, filterUtil);
1317 } else if (source == batchAnnotationSetChangeItem) {
1318 AnnotatorUtil.batchAnnotationSetChange(this, kpu, annotationUtil, filterUtil);
1319 } else if (source == iaaItem) {
1320 IAAWizard wizard = new IAAWizard(getProject(), getKnowledgeBase(), kpu, getProtegeFrame());
1321 wizard.setVisible(true);
1322 if (wizard.isGoClicked()) {
1323 try {
1324 File outputDirectory = wizard.getOutputDirectory();
1325 SimpleInstance filter = wizard.getFilter();
1326 Set<SimpleInstance> textSources = wizard.getTextSources();
1327 SimpleInstance slotMatcherConfig = wizard.getSlotMatcherConfig();
1328 Set<Slot> simpleSlots = null;
1329 Set<Slot> complexSlots = null;
1330 if (slotMatcherConfig != null) {
1331 simpleSlots = KnowtatorIAA.getSimpleSlotsFromMatcherConfig(slotMatcherConfig, kpu);
1332 complexSlots = KnowtatorIAA.getComplexSlotsFromMatcherConfig(slotMatcherConfig, kpu);
1333 }
1334 KnowtatorIAA knowtatorIAA = new KnowtatorIAA(outputDirectory, filter, textSources, getProject(),
1335 simpleSlots, complexSlots, manager, textSourceUtil.getCurrentTextSourceCollection(),
1336 annotationUtil, mentionUtil, filterUtil);
1337
1338 if (wizard.isClassMatcherSelected())
1339 knowtatorIAA.runClassIAA();
1340 if (wizard.isSpanMatcherSelected())
1341 knowtatorIAA.runSpanIAA();
1342 if (wizard.isClassAndSpanMatcherSelected())
1343 knowtatorIAA.runClassAndSpanIAA();
1344 if (wizard.isSubclassMatcherSelected())
1345 knowtatorIAA.runSubclassIAA();
1346 if (slotMatcherConfig != null) {
1347 knowtatorIAA.runFeatureMatcherIAA(slotMatcherConfig);
1348 }
1349
1350 JOptionPane.showMessageDialog(this, "IAA results written to " + outputDirectory.getPath());
1351
1352 } catch (IAAException iaae) {
1353 JOptionPane.showMessageDialog(this, "An exception occured while calculating IAA: "
1354 + iaae.getMessage() + "\nPlease see output window for a stack trace.", "IAA Exception",
1355 JOptionPane.ERROR_MESSAGE);
1356 iaae.printStackTrace();
1357 }
1358 }
1359 } else if (command.equals(SELECT_PREVIOUS_ANNOTATION_FILTER)) {
1360 try {
1361 filterUtil.selectPreviousFilter(FilterUtil.ANY_FILTER);
1362 } catch (ConsensusException ce) {
1363 JOptionPane.showMessageDialog(Knowtator.this, ce.getMessage(), "Consensus Set Error",
1364 JOptionPane.ERROR_MESSAGE);
1365 ce.printStackTrace();
1366 }
1367 } else if (command.equals(SELECT_NEXT_ANNOTATION_FILTER)) {
1368 try {
1369 filterUtil.selectNextFilter(FilterUtil.ANY_FILTER);
1370 } catch (ConsensusException ce) {
1371 JOptionPane.showMessageDialog(Knowtator.this, ce.getMessage(), "Consensus Set Error",
1372 JOptionPane.ERROR_MESSAGE);
1373 ce.printStackTrace();
1374 }
1375 } else if (command.equals(SELECT_FILTER)) {
1376 selectFilterInstance();
1377 } else if (command.equals(Knowtator.CHANGE_SORT_METHOD)) {
1378 String[] values = new String[] { "Sort alphabetically", "Sort by span indices" };
1379 Object selectionValue = JOptionPane.showInputDialog(this, "Select a sort method.", "Sort method selection",
1380 JOptionPane.PLAIN_MESSAGE, null, values, values[0]);
1381 if (selectionValue.equals(values[0])) {
1382 manager.setAnnotationComparator(alphabeticalComparator);
1383 } else {
1384 manager.setAnnotationComparator(spanComparator);
1385 }
1386 manager.updateCurrentAnnotations();
1387 } else if (source == consensusSetItem) {
1388 if (consensusSetItem.isSelected())
1389 startConsensusMode();
1390 else
1391 stopConsensusMode();
1392 }
1393 }
1394
1395 private void startConsensusMode() {
1396 try {
1397 SimpleInstance nextFilter = filterUtil.getNextFilter(FilterUtil.CONSENSUS_FILTER);
1398 if (nextFilter != null) {
1399 manager.setSelectedFilter(nextFilter);
1400 } else {
1401 consensusModeCreateButton.doClick();
1402 }
1403 } catch (ConsensusException ce) {
1404 JOptionPane.showMessageDialog(Knowtator.this, ce.getMessage(), "Consensus Set Error",
1405 JOptionPane.ERROR_MESSAGE);
1406 ce.printStackTrace();
1407 }
1408 }
1409
1410 private void stopConsensusMode() {
1411 try {
1412 SimpleInstance nextFilter = filterUtil.getNextFilter(FilterUtil.NONCONSENSUS_FILTER);
1413 if (nextFilter != null)
1414 manager.setSelectedFilter(nextFilter);
1415 else {
1416 manager.setSelectedFilter(kpu.getShowAllFilter());
1417 }
1418 } catch (ConsensusException ce) {
1419 ce.printStackTrace();// this code should be unreachable
1420 }
1421 }
1422
1423 /**
1424 * removing the instance from currentInstances was interferring with the
1425 * code that changes the type of an instance. The instances directType would
1426 * be changed causing the clsListener to trigger directInstanceRemoved on
1427 * the class that was the old directType of the instance. This would remove
1428 * the instance from the currentInstances list. I tried to add it back in
1429 * after the directType was changed but this behaved erratically.
1430 *
1431 * Use of currentInstances will have to be aware that the list may contain
1432 * deleted instances. In HighlightSpans - I simply remove instances that
1433 * cause a NullPointerException from currentInstances.
1434 *
1435 * I should probably have a InstanceListener instead.
1436 */
1437
1438 // private ClsListener _clsListener = new ClsAdapter()
1439 // {
1440 // public void directInstanceRemoved(ClsEvent event) {
1441 // // currentInstances.remove(event.getInstance());
1442 // }
1443 // };
1444 public void dispose() {
1445 try {
1446 JMenuBar menuBar = getMainWindowMenuBar();
1447 menuBar.remove(knowtatorMenu);
1448
1449 configureMenuItem.removeActionListener(this);
1450 exportToXMLMenuItem.removeActionListener(this);
1451 importFromXMLMenuItem.removeActionListener(this);
1452 annotationRemovalMenuItem.removeActionListener(this);
1453 showInstancesMenuItem.removeActionListener(this);
1454 mergeAnnotationsItem.removeActionListener(this);
1455 batchAnnotatorChangeItem.removeActionListener(this);
1456 iaaItem.removeActionListener(this);
1457
1458 knowtatorMenu.remove(configureMenuItem);
1459 knowtatorMenu.remove(exportToXMLMenuItem);
1460 knowtatorMenu.remove(importFromXMLMenuItem);
1461 knowtatorMenu.remove(annotationRemovalMenuItem);
1462 knowtatorMenu.remove(showInstancesMenuItem);
1463 knowtatorMenu.remove(mergeAnnotationsItem);
1464 knowtatorMenu.remove(batchAnnotatorChangeItem);
1465 knowtatorMenu.remove(iaaItem);
1466
1467 configureMenuItem = null;
1468 exportToXMLMenuItem = null;
1469 importFromXMLMenuItem = null;
1470 annotationRemovalMenuItem = null;
1471 showInstancesMenuItem = null;
1472 mergeAnnotationsItem = null;
1473 batchAnnotatorChangeItem = null;
1474 iaaItem = null;
1475
1476 getMainWindowToolBar().remove(filterSelectionLabel);
1477 getMainWindowToolBar().remove(prevFilterButton);
1478 getMainWindowToolBar().remove(selectAnnotationFilterButton);
1479 getMainWindowToolBar().remove(nextFilterButton);
1480 getMainWindowToolBar().remove(
1481 getMainWindowToolBar().getComponent(getMainWindowToolBar().getComponentCount() - 1));
1482 getMainWindowToolBar().remove(
1483 getMainWindowToolBar().getComponent(getMainWindowToolBar().getComponentCount() - 1));
1484 getMainWindowToolBar().remove(
1485 getMainWindowToolBar().getComponent(getMainWindowToolBar().getComponentCount() - 1));
1486 getMainWindowToolBar().remove(
1487 getMainWindowToolBar().getComponent(getMainWindowToolBar().getComponentCount() - 1));
1488
1489 instancesList.removeMouseListener(instancesListMouseListener);
1490
1491 textSourceUtil.removeTextSourceChangeListener(textViewer);
1492 textSourceUtil.removeTextSourceChangeListener(this);
1493 textSourceUtil.removeTextSourceChangeListener(spanUtil);
1494
1495 EventHandler.getInstance().dispose();
1496 textSourceSelector.dispose();
1497 } catch (Exception exception) // null pointer exceptions can be thrown
1498 // if menu doesn't exist. This can
1499 // happen when user configures Protege
1500 // to use knowtator but then cancel when
1501 // asked to save and reload.
1502 {
1503 exception.printStackTrace();
1504 }
1505 super.dispose();
1506 }
1507
1508 /**
1509 * Protege uses a custom class loader
1510 * (edu.stanford.smi.protege.util.DirectoryClassLoader) to load the jar
1511 * files in the plug-in directories. When Java loads a UI class, it uses the
1512 * default system class loader (AppClassLoader). When attempting to load the
1513 * custom UI class ScrollableBarUI, it was not found because the system
1514 * class loader doesn't load classes in the protege plug-in directories.
1515 *
1516 * This method sets the UI class loader to the Protege custom class loader,
1517 * so it can find the necessary UI classes.
1518 */
1519 private void setUIClassLoader() {
1520 ClassLoader loader = getClass().getClassLoader();
1521 UIDefaults uiDefaults = UIManager.getDefaults();
1522 uiDefaults.put("ClassLoader", loader);
1523 }
1524
1525 @SuppressWarnings("serial")
1526 private class SaveAsAction extends AbstractAction {
1527 public SaveAsAction() {
1528 super("Save Knowtator Project As...");
1529 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit()
1530 .getMenuShortcutKeyMask()));
1531 putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_V));
1532 }
1533
1534 public void actionPerformed(ActionEvent evt) {
1535 JFileChooser chooser = new JFileChooser();
1536 File projectFile = new File(getProject().getProjectDirectoryURI());
1537 System.out.println(projectFile);
1538 if (projectFile != null) {
1539 chooser.setSelectedFile(projectFile);
1540 }
1541 chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1542 chooser.setDialogTitle("Save Knowtator Project As.... Please provide project name.");
1543 int returnVal = chooser.showOpenDialog(Knowtator.this);
1544 if (returnVal == JFileChooser.APPROVE_OPTION) {
1545 File file = chooser.getSelectedFile();
1546 if (!file.getParentFile().exists())
1547 file.getParentFile().mkdirs();
1548 try {
1549 ProjectUtil.saveProjectAs(getProject(), file);
1550 ApplicationProperties.addProjectToMRUList(getProject().getProjectURI());
1551 resetProtegeTitle(getProject());
1552 JOptionPane.showMessageDialog(Knowtator.this,
1553 "Please reopen your text source collection if it is no longer visible",
1554 "Reopen Text Source Collection", JOptionPane.INFORMATION_MESSAGE);
1555
1556 } catch (IOException ioe) {
1557 JOptionPane.showMessageDialog(Knowtator.this, "Unable to save file" + ioe.getMessage(), "",
1558 JOptionPane.ERROR_MESSAGE);
1559
1560 }
1561 }
1562 }
1563 }
1564
1565 /**
1566 * This code was copied and modified from
1567 * {@link edu.stanford.smi.protege.ui.ProjectManager#updateUI()}
1568 *
1569 * @param project
1570 */
1571 public static void resetProtegeTitle(Project project) {
1572 URI uri = project.getProjectURI();
1573 String shortname = URIUtilities.getBaseName(uri);
1574 String longname = URIUtilities.getDisplayText(uri);
1575 KnowledgeBaseFactory factory = project.getKnowledgeBaseFactory();
1576 String backend = "";
1577 if (factory != null) {
1578 backend = ", " + factory.getDescription();
1579 }
1580 String programName = Text.getProgramNameAndVersion();
1581 String text = shortname + " " + programName + " (" + longname + backend + ")";
1582
1583 ComponentUtilities.setFrameTitle(ProjectManager.getProjectManager().getMainPanel(), text);
1584
1585 }
1586
1587 @SuppressWarnings("serial")
1588 private class NewProjectAction extends AbstractAction {
1589 public NewProjectAction() {
1590 super("New Knowtator Project...");
1591 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_K, Toolkit.getDefaultToolkit()
1592 .getMenuShortcutKeyMask()));
1593 putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_K));
1594 }
1595
1596 public void actionPerformed(ActionEvent evt) {
1597 File projectFile = new File(getProject().getProjectDirectoryURI());
1598 if (ProjectManager.getProjectManager().closeProjectRequest()) {
1599 JFileChooser chooser = new JFileChooser();
1600 if (projectFile != null) {
1601 chooser.setSelectedFile(projectFile);
1602 }
1603 chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1604 chooser.setDialogTitle("Create New Knowtator Project. Please provide project name.");
1605 int returnVal = chooser.showOpenDialog(Knowtator.this);
1606 if (returnVal == JFileChooser.APPROVE_OPTION) {
1607 projectFile = chooser.getSelectedFile();
1608 try {
1609 Project project = ProjectUtil.createNewProject(projectFile);
1610 URI uri = project.getProjectURI();
1611 ProjectManager.getProjectManager().loadProject(uri);
1612 } catch (IOException ioe) {
1613 JOptionPane.showMessageDialog(Knowtator.this, "Unable to save file" + ioe.getMessage(), "",
1614 JOptionPane.ERROR_MESSAGE);
1615 }
1616 }
1617 }
1618 }
1619 }
1620
1621 /**
1622 * For testing/debuging purposes only.
1623 *
1624 * @param args
1625 */
1626 public static void main(String[] args) {
1627 edu.stanford.smi.protege.Application.main(args);
1628 }
1629 }