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    }