1   /*
2    *  Copyright (c) 1998-2001, The University of Sheffield.
3    *
4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
5    *  software, licenced under the GNU Library General Public License,
6    *  Version 2, June 1991 (in the distribution as file licence.html,
7    *  and also available at http://gate.ac.uk/gate/licence.html).
8    *
9    *  Valentin Tablan 22/01/2001
10   *
11   *  $Id: MainFrame.java,v 1.177 2003/07/29 12:45:46 valyt Exp $
12   *
13   */
14  
15  package gate.gui;
16  
17  import java.awt.*;
18  import java.awt.event.*;
19  import java.beans.*;
20  import java.io.*;
21  import java.net.*;
22  import java.text.*;
23  import java.util.*;
24  import java.util.List;
25  
26  import javax.swing.*;
27  import javax.swing.event.*;
28  import javax.swing.tree.*;
29  
30  //import guk.im.*;
31  /**needed in order to register the Ontology Editor Tool
32   * ontotext.bp*/
33  import com.ontotext.gate.vr.*;
34  import gate.*;
35  import gate.creole.*;
36  import gate.event.*;
37  import gate.persist.*;
38  import gate.security.*;
39  import gate.swing.*;
40  import gate.util.*;
41  import junit.framework.*;
42  
43  /**
44   * The main Gate GUI frame.
45   */
46  public class MainFrame extends JFrame
47                      implements ProgressListener, StatusListener, CreoleListener{
48  
49    JMenuBar menuBar;
50    JSplitPane mainSplit;
51    JSplitPane leftSplit;
52    JLabel statusBar;
53    JProgressBar progressBar;
54    XJTabbedPane mainTabbedPane;
55    JScrollPane projectTreeScroll;
56    JScrollPane lowerScroll;
57  
58    JPopupMenu appsPopup;
59    JPopupMenu dssPopup;
60    JPopupMenu lrsPopup;
61    JPopupMenu prsPopup;
62  
63    /** used in popups */
64    JMenu newLrsPopupMenu;
65    JMenu newPrsPopupMenu;
66    JMenu newAppPopupMenu;
67  
68    /** used in menu bar */
69    JMenu newLrMenu;
70    JMenu newPrMenu;
71    JMenu newAppMenu;
72    JMenu loadANNIEMenu = null;
73    JButton stopBtnx;
74    Action stopActionx;
75  
76    JTree resourcesTree;
77    JScrollPane resourcesTreeScroll;
78    DefaultTreeModel resourcesTreeModel;
79    DefaultMutableTreeNode resourcesTreeRoot;
80    DefaultMutableTreeNode applicationsRoot;
81    DefaultMutableTreeNode languageResourcesRoot;
82    DefaultMutableTreeNode processingResourcesRoot;
83    DefaultMutableTreeNode datastoresRoot;
84  
85  
86  
87  
88    Splash splash;
89    LogArea logArea;
90    JScrollPane logScroll;
91    JToolBar toolbar;
92    static JFileChooser fileChooser;
93  
94    AppearanceDialog appearanceDialog;
95    OptionsDialog optionsDialog;
96    CartoonMinder animator;
97    TabHighlighter logHighlighter;
98    NewResourceDialog newResourceDialog;
99    WaitDialog waitDialog;
100 
101   NewDSAction newDSAction;
102   OpenDSAction openDSAction;
103   HelpAboutAction helpAboutAction;
104   NewAnnotDiffAction newAnnotDiffAction = null;
105   NewCorpusAnnotDiffAction newCorpusAnnotDiffAction = null;
106   NewBootStrapAction newBootStrapAction = null;
107   NewCorpusEvalAction newCorpusEvalAction = null;
108   GenerateStoredCorpusEvalAction generateStoredCorpusEvalAction = null;
109   StoredMarkedCorpusEvalAction storedMarkedCorpusEvalAction = null;
110   CleanMarkedCorpusEvalAction cleanMarkedCorpusEvalAction = null;
111   VerboseModeCorpusEvalToolAction verboseModeCorpusEvalToolAction = null;
112 //  DatastoreModeCorpusEvalToolAction datastoreModeCorpusEvalToolAction = null;
113 
114   /**ontology editor action
115    * ontotext.bp*/
116   NewOntologyEditorAction newOntologyEditorAction = null;
117 
118   NewGazetteerEditorAction  newGazetteerEditorAction = null;
119 
120 
121   /**
122    * Holds all the icons used in the Gate GUI indexed by filename.
123    * This is needed so we do not need to decode the icon everytime
124    * we need it as that would use unecessary CPU time and memory.
125    * Access to this data is avaialable through the {@link #getIcon(String)}
126    * method.
127    */
128   static Map iconByName = new HashMap();
129 
130   /**
131    * A Map which holds listeners that are singletons (e.g. the status listener
132    * that updates the status bar on the main frame or the progress listener that
133    * updates the progress bar on the main frame).
134    * The keys used are the class names of the listener interface and the values
135    * are the actual listeners (e.g "gate.event.StatusListener" -> this).
136    */
137   private static java.util.Map listeners = new HashMap();
138   protected static java.util.Collection guiRoots = new ArrayList();
139 
140   private static JDialog guiLock = null;
141 
142   static public Icon getIcon(String filename){
143     Icon result = (Icon)iconByName.get(filename);
144     if(result == null){
145       try{
146         result = new ImageIcon(new URL("gate:/img/" + filename));
147         iconByName.put(filename, result);
148       }catch(MalformedURLException mue){
149         mue.printStackTrace(Err.getPrintWriter());
150       }
151     }
152     return result;
153   }
154 
155 
156 /*
157   static public MainFrame getInstance(){
158     if(instance == null) instance = new MainFrame();
159     return instance;
160   }
161 */
162 
163   static public JFileChooser getFileChooser(){
164     return fileChooser;
165   }
166 
167 
168   /**
169    * Selects a resource if loaded in the system and not invisible.
170    * @param res the resource to be selected.
171    */
172   public void select(Resource res){
173     //first find the handle for the resource
174     Handle handle = null;
175     //go through all the nodes
176     Enumeration nodesEnum = resourcesTreeRoot.breadthFirstEnumeration();
177     while(nodesEnum.hasMoreElements() && handle == null){
178       Object node = nodesEnum.nextElement();
179       if(node instanceof DefaultMutableTreeNode){
180         DefaultMutableTreeNode dmtNode = (DefaultMutableTreeNode)node;
181         if(dmtNode.getUserObject() instanceof Handle){
182           if(((Handle)dmtNode.getUserObject()).getTarget() == res){
183             handle = (Handle)dmtNode.getUserObject();
184           }
185         }
186       }
187     }
188 
189     //now select the handle if found
190     if(handle != null) select(handle);
191   }
192 
193   protected void select(Handle handle){
194     if(mainTabbedPane.indexOfComponent(handle.getLargeView()) != -1) {
195       //select
196       JComponent largeView = handle.getLargeView();
197       if(largeView != null) {
198         mainTabbedPane.setSelectedComponent(largeView);
199       }
200       JComponent smallView = handle.getSmallView();
201       if(smallView != null) {
202         lowerScroll.getViewport().setView(smallView);
203       } else {
204         lowerScroll.getViewport().setView(null);
205       }
206     } else {
207       //show
208       JComponent largeView = handle.getLargeView();
209       if(largeView != null) {
210         mainTabbedPane.addTab(handle.getTitle(), handle.getIcon(),
211                               largeView, handle.getTooltipText());
212         mainTabbedPane.setSelectedComponent(handle.getLargeView());
213       }
214       JComponent smallView = handle.getSmallView();
215       if(smallView != null) {
216         lowerScroll.getViewport().setView(smallView);
217       } else {
218         lowerScroll.getViewport().setView(null);
219       }
220     }
221   }//protected void select(ResourceHandle handle)
222 
223   public MainFrame() {
224     this(false);
225   } // MainFrame
226 
227   /**Construct the frame*/
228   public MainFrame(boolean isShellSlacGIU) {
229     guiRoots.add(this);
230     if(fileChooser == null){
231       fileChooser = new JFileChooser();
232       fileChooser.setMultiSelectionEnabled(false);
233       guiRoots.add(fileChooser);
234 
235       //the JFileChooser seems to size itself better once it's been added to a
236       //top level container such as a dialog.
237       JDialog dialog = new JDialog(this, "", true);
238       java.awt.Container contentPane = dialog.getContentPane();
239       contentPane.setLayout(new BorderLayout());
240       contentPane.add(fileChooser, BorderLayout.CENTER);
241       dialog.pack();
242       dialog.getContentPane().removeAll();
243       dialog.dispose();
244       dialog = null;
245     }
246     enableEvents(AWTEvent.WINDOW_EVENT_MASK);
247     initLocalData(isShellSlacGIU);
248     initGuiComponents(isShellSlacGIU);
249     initListeners(isShellSlacGIU);
250   } // MainFrame(boolean simple)
251 
252   protected void initLocalData(boolean isShellSlacGIU){
253     resourcesTreeRoot = new DefaultMutableTreeNode("Gate", true);
254     applicationsRoot = new DefaultMutableTreeNode("Applications", true);
255     if(isShellSlacGIU) {
256       languageResourcesRoot = new DefaultMutableTreeNode("Documents",
257                                                        true);
258     } else {
259       languageResourcesRoot = new DefaultMutableTreeNode("Language Resources",
260                                                        true);
261     } // if
262     processingResourcesRoot = new DefaultMutableTreeNode("Processing Resources",
263                                                          true);
264     datastoresRoot = new DefaultMutableTreeNode("Data stores", true);
265     resourcesTreeRoot.add(applicationsRoot);
266     resourcesTreeRoot.add(languageResourcesRoot);
267     resourcesTreeRoot.add(processingResourcesRoot);
268     resourcesTreeRoot.add(datastoresRoot);
269 
270     resourcesTreeModel = new ResourcesTreeModel(resourcesTreeRoot, true);
271 
272     newDSAction = new NewDSAction();
273     openDSAction = new OpenDSAction();
274     helpAboutAction = new HelpAboutAction();
275     newAnnotDiffAction = new NewAnnotDiffAction();
276     newCorpusAnnotDiffAction = new NewCorpusAnnotDiffAction();
277     newBootStrapAction = new NewBootStrapAction();
278     newCorpusEvalAction = new NewCorpusEvalAction();
279     storedMarkedCorpusEvalAction = new StoredMarkedCorpusEvalAction();
280     generateStoredCorpusEvalAction = new GenerateStoredCorpusEvalAction();
281     cleanMarkedCorpusEvalAction = new CleanMarkedCorpusEvalAction();
282     verboseModeCorpusEvalToolAction = new VerboseModeCorpusEvalToolAction();
283 //    datastoreModeCorpusEvalToolAction = new DatastoreModeCorpusEvalToolAction();
284 
285     /*ontology editor action initialization
286     ontotext.bp*/
287     newOntologyEditorAction = new NewOntologyEditorAction();
288 
289     newGazetteerEditorAction = new NewGazetteerEditorAction();
290 
291   }
292 
293   protected void initGuiComponents(boolean isShellSlacGIU){
294     this.getContentPane().setLayout(new BorderLayout());
295 
296     Integer width =Gate.getUserConfig().getInt(GateConstants.MAIN_FRAME_WIDTH);
297     Integer height =Gate.getUserConfig().getInt(GateConstants.MAIN_FRAME_HEIGHT);
298     this.setSize(new Dimension(width == null ? 800 : width.intValue(),
299                                height == null ? 600 : height.intValue()));
300 
301     try{
302       this.setIconImage(Toolkit.getDefaultToolkit().getImage(
303             new URL("gate:/img/gateIcon.gif")));
304     }catch(MalformedURLException mue){
305       mue.printStackTrace(Err.getPrintWriter());
306     }
307     resourcesTree = new JTree(resourcesTreeModel){
308       public void updateUI(){
309         super.updateUI();
310         setRowHeight(0);
311       }
312     };
313 
314     resourcesTree.setEditable(true);
315     ResourcesTreeCellRenderer treeCellRenderer =
316                               new ResourcesTreeCellRenderer();
317     resourcesTree.setCellRenderer(treeCellRenderer);
318     resourcesTree.setCellEditor(new ResourcesTreeCellEditor(resourcesTree,
319                                                           treeCellRenderer));
320 
321     resourcesTree.setRowHeight(0);
322     //expand all nodes
323     resourcesTree.expandRow(0);
324     resourcesTree.expandRow(1);
325     resourcesTree.expandRow(2);
326     resourcesTree.expandRow(3);
327     resourcesTree.expandRow(4);
328     resourcesTree.getSelectionModel().
329                   setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION
330                                    );
331     resourcesTree.setEnabled(true);
332     ToolTipManager.sharedInstance().registerComponent(resourcesTree);
333     resourcesTreeScroll = new JScrollPane(resourcesTree);
334 
335     lowerScroll = new JScrollPane();
336     JPanel lowerPane = new JPanel();
337     lowerPane.setLayout(new OverlayLayout(lowerPane));
338 
339     JPanel animationPane = new JPanel();
340     animationPane.setOpaque(false);
341     animationPane.setLayout(new BoxLayout(animationPane, BoxLayout.X_AXIS));
342 
343     JPanel vBox = new JPanel();
344     vBox.setLayout(new BoxLayout(vBox, BoxLayout.Y_AXIS));
345     vBox.setOpaque(false);
346 
347     JPanel hBox = new JPanel();
348     hBox.setLayout(new BoxLayout(hBox, BoxLayout.X_AXIS));
349     hBox.setOpaque(false);
350 
351     vBox.add(Box.createVerticalGlue());
352     vBox.add(animationPane);
353 
354     hBox.add(vBox);
355     hBox.add(Box.createHorizontalGlue());
356 
357     lowerPane.add(hBox);
358     lowerPane.add(lowerScroll);
359 
360     animator = new CartoonMinder(animationPane);
361     Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
362                                animator,
363                                "MainFrame1");
364     thread.setPriority(Thread.MIN_PRIORITY);
365     thread.start();
366 
367     leftSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
368                                resourcesTreeScroll, lowerPane);
369 
370     leftSplit.setResizeWeight((double)0.7);
371 
372     // Create a new logArea and redirect the Out and Err output to it.
373     logArea = new LogArea();
374     logScroll = new JScrollPane(logArea);
375     // Out has been redirected to the logArea
376     Out.prln("Gate 2 started at: " + new Date().toString());
377     mainTabbedPane = new XJTabbedPane(JTabbedPane.TOP);
378     mainTabbedPane.insertTab("Messages",null, logScroll, "Gate log", 0);
379 
380     logHighlighter = new TabHighlighter(mainTabbedPane, logScroll, Color.red);
381 
382 
383     mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
384                                leftSplit, mainTabbedPane);
385 
386     mainSplit.setDividerLocation(leftSplit.getPreferredSize().width + 10);
387     this.getContentPane().add(mainSplit, BorderLayout.CENTER);
388 
389     //status and progress bars
390     statusBar = new JLabel(" ");
391     statusBar.setPreferredSize(new Dimension(200,
392                                              statusBar.getPreferredSize().
393                                              height));
394 
395     UIManager.put("ProgressBar.cellSpacing", new Integer(0));
396     progressBar = new JProgressBar(JProgressBar.HORIZONTAL);
397     progressBar.setBorder(BorderFactory.createEmptyBorder());
398     progressBar.setForeground(new Color(150, 75, 150));
399     progressBar.setBorderPainted(false);
400     progressBar.setStringPainted(false);
401     progressBar.setOrientation(JProgressBar.HORIZONTAL);
402 
403     JPanel southBox = new JPanel();
404     southBox.setLayout(new GridLayout(1,2));
405     southBox.setBorder(null);
406 
407     Box tempHBox = Box.createHorizontalBox();
408     tempHBox.add(Box.createHorizontalStrut(5));
409     tempHBox.add(statusBar);
410     southBox.add(tempHBox);
411     tempHBox = Box.createHorizontalBox();
412     tempHBox.add(progressBar);
413     tempHBox.add(Box.createHorizontalStrut(5));
414     southBox.add(tempHBox);
415 
416     this.getContentPane().add(southBox, BorderLayout.SOUTH);
417     progressBar.setVisible(false);
418 
419     //TOOLBAR
420     toolbar = new JToolBar(JToolBar.HORIZONTAL);
421     toolbar.setFloatable(false);
422     //toolbar.add(new JGateButton(newProjectAction));
423 
424 
425     this.getContentPane().add(toolbar, BorderLayout.NORTH);
426 
427     //extra stuff
428     newResourceDialog = new NewResourceDialog(
429       this, "Resource parameters", true
430     );
431     waitDialog = new WaitDialog(this, "");
432     //build the Help->About dialog
433     JPanel splashBox = new JPanel();
434     splashBox.setLayout(new BoxLayout(splashBox, BoxLayout.Y_AXIS));
435     splashBox.setBackground(Color.white);
436 
437     JLabel gifLbl = new JLabel(getIcon("gateSplash.gif"));
438     Box box = new Box(BoxLayout.X_AXIS);
439     box.add(Box.createHorizontalGlue());
440     box.add(gifLbl);
441     box.add(Box.createHorizontalGlue());
442     splashBox.add(box);
443 
444     gifLbl = new JLabel(getIcon("gateHeader.gif"));
445     box = new Box(BoxLayout.X_AXIS);
446     box.add(gifLbl);
447     box.add(Box.createHorizontalGlue());
448     splashBox.add(box);
449     splashBox.add(Box.createVerticalStrut(10));
450 
451     JLabel verLbl = new JLabel(
452       "<HTML><FONT color=\"blue\">Version <B>"
453       + Main.version + "</B></FONT>" +
454       ", <FONT color=\"red\">build <B>" + Main.build + "</B></FONT></HTML>"
455     );
456     box = new Box(BoxLayout.X_AXIS);
457     box.add(Box.createHorizontalGlue());
458     box.add(verLbl);
459 
460     splashBox.add(box);
461     splashBox.add(Box.createVerticalStrut(10));
462 
463     verLbl = new JLabel(
464 "<HTML>" +
465 "<B>Hamish Cunningham, Valentin Tablan, Kalina Bontcheva, Diana Maynard,</B>" +
466 "<BR>Cristian Ursu, Marin Dimitrov, Oana Hamza, Horacio Saggion," +
467 "<BR>Atanas Kiryakov, Angel Kirilov, Bobby Popov, Damyan Ognyanoff," +
468 "<BR>Robert Gaizauskas, Mark Hepple, Mark Leisher, " +
469 "Kevin Humphreys, Yorick Wilks." +
470 "<P><B>JVM version</B>: " + System.getProperty("java.version") +
471 " from " + System.getProperty("java.vendor")
472     );
473     box = new Box(BoxLayout.X_AXIS);
474     box.add(verLbl);
475     box.add(Box.createHorizontalGlue());
476 
477     splashBox.add(box);
478 
479     JButton okBtn = new JButton("OK");
480     okBtn.addActionListener(new ActionListener() {
481       public void actionPerformed(ActionEvent e) {
482         splash.hide();
483       }
484     });
485     okBtn.setBackground(Color.white);
486     box = new Box(BoxLayout.X_AXIS);
487     box.add(Box.createHorizontalGlue());
488     box.add(okBtn);
489     box.add(Box.createHorizontalGlue());
490 
491     splashBox.add(Box.createVerticalStrut(10));
492     splashBox.add(box);
493     splashBox.add(Box.createVerticalStrut(10));
494     splash = new Splash(this, splashBox);
495 
496 
497     //MENUS
498     menuBar = new JMenuBar();
499 
500 
501     JMenu fileMenu = new XJMenu("File");
502 
503     newLrMenu = new XJMenu("New language resource");
504     fileMenu.add(newLrMenu);
505     newPrMenu = new XJMenu("New processing resource");
506     fileMenu.add(newPrMenu);
507 
508     newAppMenu = new JMenu("New application");
509     fileMenu.add(newAppMenu);
510 
511     fileMenu.addSeparator();
512     fileMenu.add(new XJMenuItem(new LoadResourceFromFileAction(), this));
513 
514     fileMenu.addSeparator();
515     fileMenu.add(new XJMenuItem(newDSAction, this));
516     fileMenu.add(new XJMenuItem(openDSAction, this));
517     fileMenu.addSeparator();
518     loadANNIEMenu = new JMenu("Load ANNIE system");
519     fileMenu.add(loadANNIEMenu);
520     fileMenu.add(new XJMenuItem(new LoadCreoleRepositoryAction(), this));
521     fileMenu.addSeparator();
522 
523     fileMenu.add(new XJMenuItem(new ExitGateAction(), this));
524     menuBar.add(fileMenu);
525 
526 
527 
528     JMenu optionsMenu = new JMenu("Options");
529 
530     optionsDialog = new OptionsDialog(MainFrame.this);
531     optionsMenu.add(new XJMenuItem(new AbstractAction("Configuration"){
532       {
533         putValue(SHORT_DESCRIPTION, "Edit gate options");
534       }
535       public void actionPerformed(ActionEvent evt){
536         optionsDialog.show();
537       }
538     }, this));
539 
540 
541     JMenu imMenu = null;
542     List installedLocales = new ArrayList();
543     try{
544       //if this fails guk is not present
545       Class.forName("guk.im.GateIMDescriptor");
546       //add the Gate input methods
547       installedLocales.addAll(Arrays.asList(new guk.im.GateIMDescriptor().
548                                             getAvailableLocales()));
549     }catch(Exception e){
550       //something happened; most probably guk not present.
551       //just drop it, is not vital.
552     }
553     try{
554       //add the MPI IMs
555       //if this fails mpi IM is not present
556       Class.forName("mpi.alt.java.awt.im.spi.lookup.LookupDescriptor");
557 
558       installedLocales.addAll(Arrays.asList(
559             new mpi.alt.java.awt.im.spi.lookup.LookupDescriptor().
560             getAvailableLocales()));
561     }catch(Exception e){
562       //something happened; most probably MPI not present.
563       //just drop it, is not vital.
564     }
565 
566     Collections.sort(installedLocales, new Comparator(){
567       public int compare(Object o1, Object o2){
568         return ((Locale)o1).getDisplayName().compareTo(((Locale)o2).getDisplayName());
569       }
570     });
571     JMenuItem item;
572     if(!installedLocales.isEmpty()){
573       imMenu = new XJMenu("Input methods");
574       ButtonGroup bg = new ButtonGroup();
575       item = new LocaleSelectorMenuItem();
576       imMenu.add(item);
577       item.setSelected(true);
578       imMenu.addSeparator();
579       bg.add(item);
580       for(int i = 0; i < installedLocales.size(); i++){
581         Locale locale = (Locale)installedLocales.get(i);
582         item = new LocaleSelectorMenuItem(locale);
583         imMenu.add(item);
584         bg.add(item);
585       }
586     }
587     if(imMenu != null) optionsMenu.add(imMenu);
588 
589     menuBar.add(optionsMenu);
590 
591     JMenu toolsMenu = new XJMenu("Tools");
592     toolsMenu.add(newAnnotDiffAction);
593     toolsMenu.add(newCorpusAnnotDiffAction);
594     toolsMenu.add(newBootStrapAction);
595     //temporarily disabled till the evaluation tools are made to run within
596     //the GUI
597     JMenu corpusEvalMenu = new JMenu("Corpus Benchmark Tools");
598     toolsMenu.add(corpusEvalMenu);
599     corpusEvalMenu.add(newCorpusEvalAction);
600     corpusEvalMenu.addSeparator();
601     corpusEvalMenu.add(generateStoredCorpusEvalAction);
602     corpusEvalMenu.addSeparator();
603     corpusEvalMenu.add(storedMarkedCorpusEvalAction);
604     corpusEvalMenu.add(cleanMarkedCorpusEvalAction);
605     corpusEvalMenu.addSeparator();
606     JCheckBoxMenuItem verboseModeItem =
607       new JCheckBoxMenuItem(verboseModeCorpusEvalToolAction);
608     corpusEvalMenu.add(verboseModeItem);
609 //    JCheckBoxMenuItem datastoreModeItem =
610 //      new JCheckBoxMenuItem(datastoreModeCorpusEvalToolAction);
611 //    corpusEvalMenu.add(datastoreModeItem);
612     toolsMenu.add(
613       new AbstractAction("Unicode editor", getIcon("unicode.gif")){
614       public void actionPerformed(ActionEvent evt){
615         new guk.Editor();
616       }
617     });
618 
619     /*add the ontology editor to the tools menu
620     ontotext.bp */
621     toolsMenu.add(newOntologyEditorAction);
622 
623     menuBar.add(toolsMenu);
624 
625     JMenu helpMenu = new JMenu("Help");
626 //    helpMenu.add(new HelpUserGuideAction());
627     helpMenu.add(helpAboutAction);
628     menuBar.add(helpMenu);
629 
630     this.setJMenuBar(menuBar);
631 
632     //popups
633     newAppPopupMenu = new XJMenu("New");
634     appsPopup = new XJPopupMenu();
635     appsPopup.add(newAppPopupMenu);
636     appsPopup.addSeparator();
637     appsPopup.add(new XJMenuItem(new LoadResourceFromFileAction(), this));
638     guiRoots.add(newAppPopupMenu);
639     guiRoots.add(appsPopup);
640 
641     newLrsPopupMenu = new XJMenu("New");
642     lrsPopup = new XJPopupMenu();
643     lrsPopup.add(newLrsPopupMenu);
644     guiRoots.add(lrsPopup);
645     guiRoots.add(newLrsPopupMenu);
646 
647     newPrsPopupMenu = new XJMenu("New");
648     prsPopup = new XJPopupMenu();
649     prsPopup.add(newPrsPopupMenu);
650     guiRoots.add(newPrsPopupMenu);
651     guiRoots.add(prsPopup);
652 
653     dssPopup = new XJPopupMenu();
654     dssPopup.add(newDSAction);
655     dssPopup.add(openDSAction);
656     guiRoots.add(dssPopup);
657   }
658 
659   protected void initListeners(boolean isShellSlacGIU){
660     Gate.getCreoleRegister().addCreoleListener(this);
661 
662     resourcesTree.addMouseListener(new MouseAdapter() {
663       public void mouseClicked(MouseEvent e) {
664         //where inside the tree?
665         int x = e.getX();
666         int y = e.getY();
667         TreePath path = resourcesTree.getPathForLocation(x, y);
668         JPopupMenu popup = null;
669         Handle handle = null;
670         if(path != null){
671           Object value = path.getLastPathComponent();
672           if(value == resourcesTreeRoot){
673           } else if(value == applicationsRoot){
674             popup = appsPopup;
675           } else if(value == languageResourcesRoot){
676             popup = lrsPopup;
677           } else if(value == processingResourcesRoot){
678             popup = prsPopup;
679           } else if(value == datastoresRoot){
680             popup = dssPopup;
681           }else{
682             value = ((DefaultMutableTreeNode)value).getUserObject();
683             if(value instanceof Handle){
684               handle = (Handle)value;
685               popup = handle.getPopup();
686             }
687           }
688         }
689         if (SwingUtilities.isRightMouseButton(e)) {
690           if(resourcesTree.getSelectionCount() > 1){
691             //multiple selection in tree-> show a popup for delete all
692             popup = new XJPopupMenu();
693             popup.add(new XJMenuItem(new CloseSelectedResourcesAction(),
694                       MainFrame.this));
695             popup.show(resourcesTree, e.getX(), e.getY());
696           }else if(popup != null){
697             if(handle != null){
698               // Create a CloseViewAction and a menu item based on it
699               CloseViewAction cva = new CloseViewAction(handle);
700               XJMenuItem menuItem = new XJMenuItem(cva, MainFrame.this);
701               // Add an accelerator ATL+F4 for this action
702               menuItem.setAccelerator(
703                     KeyStroke.getKeyStroke(KeyEvent.VK_H,
704                                            ActionEvent.CTRL_MASK));
705               popup.insert(menuItem, 1);
706               popup.insert(new JPopupMenu.Separator(), 2);
707 
708               popup.insert(new XJMenuItem(new RenameResourceAction(path),
709                                           MainFrame.this), 3);
710 
711               // Put the action command in the component's action map
712               if (handle.getLargeView() != null){
713                 handle.getLargeView().getActionMap().
714                                       put("Hide current view",cva);
715               }
716             }
717 
718 
719             popup.show(resourcesTree, e.getX(), e.getY());
720           }
721         } else if(SwingUtilities.isLeftMouseButton(e)) {
722           if(e.getClickCount() == 2 && handle != null) {
723             //double click - show the resource
724             select(handle);
725           }
726         }
727       }
728 
729       public void mousePressed(MouseEvent e) {
730       }
731 
732       public void mouseReleased(MouseEvent e) {
733       }
734 
735       public void mouseEntered(MouseEvent e) {
736       }
737 
738       public void mouseExited(MouseEvent e) {
739       }
740     });
741 
742     // Add the keyboard listeners for CTRL+F4 and ALT+F4
743     this.addKeyListener(new KeyAdapter() {
744       public void keyTyped(KeyEvent e) {
745       }
746 
747       public void keyPressed(KeyEvent e) {
748         // If Ctrl+F4 was pressed then close the active resource
749         if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_F4){
750           JComponent resource = (JComponent)
751                                         mainTabbedPane.getSelectedComponent();
752           if (resource != null){
753             Action act = resource.getActionMap().get("Close resource");
754             if (act != null)
755               act.actionPerformed(null);
756           }// End if
757         }// End if
758         // If CTRL+H was pressed then hide the active view.
759         if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_H){
760           JComponent resource = (JComponent)
761                                         mainTabbedPane.getSelectedComponent();
762           if (resource != null){
763             Action act = resource.getActionMap().get("Hide current view");
764             if (act != null)
765               act.actionPerformed(null);
766           }// End if
767         }// End if
768         // If CTRL+X was pressed then save as XML
769         if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_X){
770           JComponent resource = (JComponent)
771                                         mainTabbedPane.getSelectedComponent();
772           if (resource != null){
773             Action act = resource.getActionMap().get("Save As XML");
774             if (act != null)
775               act.actionPerformed(null);
776           }// End if
777         }// End if
778       }// End keyPressed();
779 
780       public void keyReleased(KeyEvent e) {
781       }
782     });
783 
784     mainTabbedPane.getModel().addChangeListener(new ChangeListener() {
785       public void stateChanged(ChangeEvent e) {
786         JComponent largeView = (JComponent)mainTabbedPane.getSelectedComponent();
787         Enumeration nodesEnum = resourcesTreeRoot.preorderEnumeration();
788         boolean done = false;
789         DefaultMutableTreeNode node = resourcesTreeRoot;
790         while(!done && nodesEnum.hasMoreElements()){
791           node = (DefaultMutableTreeNode)nodesEnum.nextElement();
792           done = node.getUserObject() instanceof Handle &&
793                  ((Handle)node.getUserObject()).getLargeView()
794                   == largeView;
795         }
796         if(done){
797           select((Handle)node.getUserObject());
798         }else{
799           //the selected item is not a resource (maybe the log area?)
800           lowerScroll.getViewport().setView(null);
801         }
802       }
803     });
804 
805     mainTabbedPane.addMouseListener(new MouseAdapter() {
806       public void mouseClicked(MouseEvent e) {
807         if(SwingUtilities.isRightMouseButton(e)){
808           int index = mainTabbedPane.getIndexAt(e.getPoint());
809           if(index != -1){
810             JComponent view = (JComponent)mainTabbedPane.getComponentAt(index);
811             Enumeration nodesEnum = resourcesTreeRoot.preorderEnumeration();
812             boolean done = false;
813             DefaultMutableTreeNode node = resourcesTreeRoot;
814             while(!done && nodesEnum.hasMoreElements()){
815               node = (DefaultMutableTreeNode)nodesEnum.nextElement();
816               done = node.getUserObject() instanceof Handle &&
817                      ((Handle)node.getUserObject()).getLargeView()
818                       == view;
819             }
820             if(done){
821               Handle handle = (Handle)node.getUserObject();
822               JPopupMenu popup = handle.getPopup();
823               popup.show(mainTabbedPane, e.getX(), e.getY());
824             }
825           }
826         }
827       }
828 
829       public void mousePressed(MouseEvent e) {
830       }
831 
832       public void mouseReleased(MouseEvent e) {
833       }
834 
835       public void mouseEntered(MouseEvent e) {
836       }
837 
838       public void mouseExited(MouseEvent e) {
839       }
840     });
841 
842     addComponentListener(new ComponentAdapter() {
843       public void componentHidden(ComponentEvent e) {
844 
845       }
846 
847       public void componentMoved(ComponentEvent e) {
848       }
849 
850       public void componentResized(ComponentEvent e) {
851       }
852 
853       public void componentShown(ComponentEvent e) {
854         leftSplit.setDividerLocation((double)0.7);
855       }
856     });
857 
858     if(isShellSlacGIU) {
859       mainSplit.setDividerSize(0);
860       mainSplit.getTopComponent().setVisible(false);
861       mainSplit.getTopComponent().addComponentListener(new ComponentAdapter() {
862         public void componentHidden(ComponentEvent e) {
863         }
864         public void componentMoved(ComponentEvent e) {
865           mainSplit.setDividerLocation(0);
866         }
867         public void componentResized(ComponentEvent e) {
868           mainSplit.setDividerLocation(0);
869         }
870         public void componentShown(ComponentEvent e) {
871           mainSplit.setDividerLocation(0);
872         }
873       });
874     } // if
875 
876     //blink the messages tab when new information is displayed
877     logArea.getDocument().addDocumentListener(new javax.swing.event.DocumentListener(){
878       public void insertUpdate(javax.swing.event.DocumentEvent e){
879         changeOccured();
880       }
881       public void removeUpdate(javax.swing.event.DocumentEvent e){
882         changeOccured();
883       }
884       public void changedUpdate(javax.swing.event.DocumentEvent e){
885         changeOccured();
886       }
887       protected void changeOccured(){
888         logHighlighter.highlight();
889       }
890     });
891 
892     logArea.addPropertyChangeListener("document", new PropertyChangeListener(){
893       public void propertyChange(PropertyChangeEvent evt){
894         //add the document listener
895         logArea.getDocument().addDocumentListener(new javax.swing.event.DocumentListener(){
896           public void insertUpdate(javax.swing.event.DocumentEvent e){
897             changeOccured();
898           }
899           public void removeUpdate(javax.swing.event.DocumentEvent e){
900             changeOccured();
901           }
902           public void changedUpdate(javax.swing.event.DocumentEvent e){
903             changeOccured();
904           }
905           protected void changeOccured(){
906             logHighlighter.highlight();
907           }
908         });
909       }
910     });
911 
912     newLrMenu.addMenuListener(new MenuListener() {
913       public void menuCanceled(MenuEvent e) {
914       }
915       public void menuDeselected(MenuEvent e) {
916       }
917       public void menuSelected(MenuEvent e) {
918         newLrMenu.removeAll();
919         //find out the available types of LRs and repopulate the menu
920         CreoleRegister reg = Gate.getCreoleRegister();
921         List lrTypes = reg.getPublicLrTypes();
922         if(lrTypes != null && !lrTypes.isEmpty()){
923           HashMap resourcesByName = new HashMap();
924           Iterator lrIter = lrTypes.iterator();
925           while(lrIter.hasNext()){
926             ResourceData rData = (ResourceData)reg.get(lrIter.next());
927             resourcesByName.put(rData.getName(), rData);
928           }
929           List lrNames = new ArrayList(resourcesByName.keySet());
930           Collections.sort(lrNames);
931           lrIter = lrNames.iterator();
932           while(lrIter.hasNext()){
933             ResourceData rData = (ResourceData)resourcesByName.
934                                  get(lrIter.next());
935             newLrMenu.add(new XJMenuItem(new NewResourceAction(rData),
936                                          MainFrame.this));
937           }
938         }
939       }
940     });
941 
942     newPrMenu.addMenuListener(new MenuListener() {
943       public void menuCanceled(MenuEvent e) {
944       }
945       public void menuDeselected(MenuEvent e) {
946       }
947       public void menuSelected(MenuEvent e) {
948         newPrMenu.removeAll();
949         //find out the available types of LRs and repopulate the menu
950         CreoleRegister reg = Gate.getCreoleRegister();
951         List prTypes = reg.getPublicPrTypes();
952         if(prTypes != null && !prTypes.isEmpty()){
953           HashMap resourcesByName = new HashMap();
954           Iterator prIter = prTypes.iterator();
955           while(prIter.hasNext()){
956             ResourceData rData = (ResourceData)reg.get(prIter.next());
957             resourcesByName.put(rData.getName(), rData);
958           }
959           List prNames = new ArrayList(resourcesByName.keySet());
960           Collections.sort(prNames);
961           prIter = prNames.iterator();
962           while(prIter.hasNext()){
963             ResourceData rData = (ResourceData)resourcesByName.
964                                  get(prIter.next());
965             newPrMenu.add(new XJMenuItem(new NewResourceAction(rData),
966                                          MainFrame.this));
967           }
968         }
969       }
970     });
971 
972     newLrsPopupMenu.addMenuListener(new MenuListener() {
973       public void menuCanceled(MenuEvent e) {
974       }
975       public void menuDeselected(MenuEvent e) {
976       }
977       public void menuSelected(MenuEvent e) {
978         newLrsPopupMenu.removeAll();
979         //find out the available types of LRs and repopulate the menu
980         CreoleRegister reg = Gate.getCreoleRegister();
981         List lrTypes = reg.getPublicLrTypes();
982         if(lrTypes != null && !lrTypes.isEmpty()){
983           HashMap resourcesByName = new HashMap();
984           Iterator lrIter = lrTypes.iterator();
985           while(lrIter.hasNext()){
986             ResourceData rData = (ResourceData)reg.get(lrIter.next());
987             resourcesByName.put(rData.getName(), rData);
988           }
989           List lrNames = new ArrayList(resourcesByName.keySet());
990           Collections.sort(lrNames);
991           lrIter = lrNames.iterator();
992           while(lrIter.hasNext()){
993             ResourceData rData = (ResourceData)resourcesByName.
994                                  get(lrIter.next());
995             newLrsPopupMenu.add(new XJMenuItem(new NewResourceAction(rData),
996                                          MainFrame.this));
997           }
998         }
999       }
1000    });
1001
1002    // Adding a listener for loading ANNIE with or without defaults
1003    loadANNIEMenu.addMenuListener(new MenuListener(){
1004      public void menuCanceled(MenuEvent e){}
1005      public void menuDeselected(MenuEvent e){}
1006      public void menuSelected(MenuEvent e){
1007        loadANNIEMenu.removeAll();
1008        loadANNIEMenu.add(new LoadANNIEWithDefaultsAction());
1009        loadANNIEMenu.add(new LoadANNIEWithoutDefaultsAction());
1010      }// menuSelected();
1011    });//loadANNIEMenu.addMenuListener(new MenuListener()
1012
1013    newPrsPopupMenu.addMenuListener(new MenuListener() {
1014      public void menuCanceled(MenuEvent e) {
1015      }
1016      public void menuDeselected(MenuEvent e) {
1017      }
1018      public void menuSelected(MenuEvent e) {
1019        newPrsPopupMenu.removeAll();
1020        //find out the available types of LRs and repopulate the menu
1021        CreoleRegister reg = Gate.getCreoleRegister();
1022        List prTypes = reg.getPublicPrTypes();
1023        if(prTypes != null && !prTypes.isEmpty()){
1024          HashMap resourcesByName = new HashMap();
1025          Iterator prIter = prTypes.iterator();
1026          while(prIter.hasNext()){
1027            ResourceData rData = (ResourceData)reg.get(prIter.next());
1028            resourcesByName.put(rData.getName(), rData);
1029          }
1030          List prNames = new ArrayList(resourcesByName.keySet());
1031          Collections.sort(prNames);
1032          prIter = prNames.iterator();
1033          while(prIter.hasNext()){
1034            ResourceData rData = (ResourceData)resourcesByName.
1035                                 get(prIter.next());
1036            newPrsPopupMenu.add(new XJMenuItem(new NewResourceAction(rData),
1037                                         MainFrame.this));
1038          }
1039        }
1040      }
1041    });
1042
1043
1044    newAppMenu.addMenuListener(new MenuListener() {
1045      public void menuCanceled(MenuEvent e) {
1046      }
1047      public void menuDeselected(MenuEvent e) {
1048      }
1049      public void menuSelected(MenuEvent e) {
1050        newAppMenu.removeAll();
1051        //find out the available types of Controllers and repopulate the menu
1052        CreoleRegister reg = Gate.getCreoleRegister();
1053        List controllerTypes = reg.getPublicControllerTypes();
1054        if(controllerTypes != null && !controllerTypes.isEmpty()){
1055          HashMap resourcesByName = new HashMap();
1056          Iterator controllerTypesIter = controllerTypes.iterator();
1057          while(controllerTypesIter.hasNext()){
1058            ResourceData rData = (ResourceData)reg.get(controllerTypesIter.next());
1059            resourcesByName.put(rData.getName(), rData);
1060          }
1061          List controllerNames = new ArrayList(resourcesByName.keySet());
1062          Collections.sort(controllerNames);
1063          controllerTypesIter = controllerNames.iterator();
1064          while(controllerTypesIter.hasNext()){
1065            ResourceData rData = (ResourceData)resourcesByName.
1066                                 get(controllerTypesIter.next());
1067            newAppMenu.add(new XJMenuItem(new NewResourceAction(rData),
1068                                         MainFrame.this));
1069          }
1070        }
1071      }
1072    });
1073
1074
1075    newAppPopupMenu.addMenuListener(new MenuListener() {
1076      public void menuCanceled(MenuEvent e) {
1077      }
1078      public void menuDeselected(MenuEvent e) {
1079      }
1080      public void menuSelected(MenuEvent e) {
1081        newAppPopupMenu.removeAll();
1082        //find out the available types of Controllers and repopulate the menu
1083        CreoleRegister reg = Gate.getCreoleRegister();
1084        List controllerTypes = reg.getPublicControllerTypes();
1085        if(controllerTypes != null && !controllerTypes.isEmpty()){
1086          HashMap resourcesByName = new HashMap();
1087          Iterator controllerTypesIter = controllerTypes.iterator();
1088          while(controllerTypesIter.hasNext()){
1089            ResourceData rData = (ResourceData)reg.get(controllerTypesIter.next());
1090            resourcesByName.put(rData.getName(), rData);
1091          }
1092          List controllerNames = new ArrayList(resourcesByName.keySet());
1093          Collections.sort(controllerNames);
1094          controllerTypesIter = controllerNames.iterator();
1095          while(controllerTypesIter.hasNext()){
1096            ResourceData rData = (ResourceData)resourcesByName.
1097                                 get(controllerTypesIter.next());
1098            newAppPopupMenu.add(new XJMenuItem(new NewResourceAction(rData),
1099                                         MainFrame.this));
1100          }
1101        }
1102      }
1103    });
1104
1105   listeners.put("gate.event.StatusListener", MainFrame.this);
1106   listeners.put("gate.event.ProgressListener", MainFrame.this);
1107  }//protected void initListeners()
1108
1109  public void progressChanged(int i) {
1110    //progressBar.setStringPainted(true);
1111    int oldValue = progressBar.getValue();
1112//    if((!stopAction.isEnabled()) &&
1113//       (Gate.getExecutable() != null)){
1114//      stopAction.setEnabled(true);
1115//      SwingUtilities.invokeLater(new Runnable(){
1116//        public void run(){
1117//          southBox.add(stopBtn, 0);
1118//        }
1119//      });
1120//    }
1121    if(!animator.isActive()) animator.activate();
1122    if(oldValue != i){
1123      SwingUtilities.invokeLater(new ProgressBarUpdater(i));
1124    }
1125  }
1126
1127  /**
1128   * Called when the process is finished.
1129   *
1130   */
1131  public void processFinished() {
1132    //progressBar.setStringPainted(false);
1133//    if(stopAction.isEnabled()){
1134//      stopAction.setEnabled(false);
1135//      SwingUtilities.invokeLater(new Runnable(){
1136//        public void run(){
1137//          southBox.remove(stopBtn);
1138//        }
1139//      });
1140//    }
1141    SwingUtilities.invokeLater(new ProgressBarUpdater(0));
1142    animator.deactivate();
1143  }
1144
1145  public void statusChanged(String text) {
1146    SwingUtilities.invokeLater(new StatusBarUpdater(text));
1147  }
1148
1149  public void resourceLoaded(CreoleEvent e) {
1150    Resource res = e.getResource();
1151    if(Gate.getHiddenAttribute(res.getFeatures())) return;
1152    NameBearerHandle handle = new NameBearerHandle(res, MainFrame.this);
1153    DefaultMutableTreeNode node = new DefaultMutableTreeNode(handle, false);
1154    if(res instanceof ProcessingResource){
1155      resourcesTreeModel.insertNodeInto(node, processingResourcesRoot, 0);
1156    }else if(res instanceof LanguageResource){
1157      resourcesTreeModel.insertNodeInto(node, languageResourcesRoot, 0);
1158    }else if(res instanceof Controller){
1159      resourcesTreeModel.insertNodeInto(node, applicationsRoot, 0);
1160    }
1161
1162    handle.addProgressListener(MainFrame.this);
1163    handle.addStatusListener(MainFrame.this);
1164
1165//    JPopupMenu popup = handle.getPopup();
1166//
1167//    // Create a CloseViewAction and a menu item based on it
1168//    CloseViewAction cva = new CloseViewAction(handle);
1169//    XJMenuItem menuItem = new XJMenuItem(cva, this);
1170//    // Add an accelerator ATL+F4 for this action
1171//    menuItem.setAccelerator(KeyStroke.getKeyStroke(
1172//                                      KeyEvent.VK_H, ActionEvent.CTRL_MASK));
1173//    popup.insert(menuItem, 1);
1174//    popup.insert(new JPopupMenu.Separator(), 2);
1175//
1176//    popup.insert(new XJMenuItem(
1177//                  new RenameResourceAction(
1178//                      new TreePath(resourcesTreeModel.getPathToRoot(node))),
1179//                  MainFrame.this) , 3);
1180//
1181//    // Put the action command in the component's action map
1182//    if (handle.getLargeView() != null)
1183//      handle.getLargeView().getActionMap().put("Hide current view",cva);
1184//
1185  }// resourceLoaded();
1186
1187
1188  public void resourceUnloaded(CreoleEvent e) {
1189    Resource res = e.getResource();
1190    if(Gate.getHiddenAttribute(res.getFeatures())) return;
1191    DefaultMutableTreeNode node;
1192    DefaultMutableTreeNode parent = null;
1193    if(res instanceof ProcessingResource){
1194      parent = processingResourcesRoot;
1195    }else if(res instanceof LanguageResource){
1196      parent = languageResourcesRoot;
1197    }else if(res instanceof Controller){
1198      parent = applicationsRoot;
1199    }
1200    if(parent != null){
1201      Enumeration children = parent.children();
1202      while(children.hasMoreElements()){
1203        node = (DefaultMutableTreeNode)children.nextElement();
1204        if(((NameBearerHandle)node.getUserObject()).getTarget() == res){
1205          resourcesTreeModel.removeNodeFromParent(node);
1206          Handle handle = (Handle)node.getUserObject();
1207          if(mainTabbedPane.indexOfComponent(handle.getLargeView()) != -1){
1208            mainTabbedPane.remove(handle.getLargeView());
1209          }
1210          if(lowerScroll.getViewport().getView() == handle.getSmallView()){
1211            lowerScroll.getViewport().setView(null);
1212          }
1213          return;
1214        }
1215      }
1216    }
1217  }
1218
1219  /**Called when a {@link gate.DataStore} has been opened*/
1220  public void datastoreOpened(CreoleEvent e){
1221    DataStore ds = e.getDatastore();
1222
1223    ds.setName(ds.getStorageUrl());
1224
1225    NameBearerHandle handle = new NameBearerHandle(ds, MainFrame.this);
1226    DefaultMutableTreeNode node = new DefaultMutableTreeNode(handle, false);
1227    resourcesTreeModel.insertNodeInto(node, datastoresRoot, 0);
1228    handle.addProgressListener(MainFrame.this);
1229    handle.addStatusListener(MainFrame.this);
1230
1231//    JPopupMenu popup = handle.getPopup();
1232//    popup.addSeparator();
1233//    // Create a CloseViewAction and a menu item based on it
1234//    CloseViewAction cva = new CloseViewAction(handle);
1235//    XJMenuItem menuItem = new XJMenuItem(cva, this);
1236//    // Add an accelerator ATL+F4 for this action
1237//    menuItem.setAccelerator(KeyStroke.getKeyStroke(
1238//                                      KeyEvent.VK_H, ActionEvent.CTRL_MASK));
1239//    popup.add(menuItem);
1240//    // Put the action command in the component's action map
1241//    if (handle.getLargeView() != null)
1242//      handle.getLargeView().getActionMap().put("Hide current view",cva);
1243  }// datastoreOpened();
1244
1245  /**Called when a {@link gate.DataStore} has been created*/
1246  public void datastoreCreated(CreoleEvent e){
1247    datastoreOpened(e);
1248  }
1249
1250  /**Called when a {@link gate.DataStore} has been closed*/
1251  public void datastoreClosed(CreoleEvent e){
1252    DataStore ds = e.getDatastore();
1253    DefaultMutableTreeNode node;
1254    DefaultMutableTreeNode parent = datastoresRoot;
1255    if(parent != null){
1256      Enumeration children = parent.children();
1257      while(children.hasMoreElements()){
1258        node = (DefaultMutableTreeNode)children.nextElement();
1259        if(((NameBearerHandle)node.getUserObject()).
1260            getTarget() == ds){
1261          resourcesTreeModel.removeNodeFromParent(node);
1262          NameBearerHandle handle = (NameBearerHandle)
1263                                          node.getUserObject();
1264          if(mainTabbedPane.indexOfComponent(handle.getLargeView()) != -1){
1265            mainTabbedPane.remove(handle.getLargeView());
1266          }
1267          if(lowerScroll.getViewport().getView() == handle.getSmallView()){
1268            lowerScroll.getViewport().setView(null);
1269          }
1270          return;
1271        }
1272      }
1273    }
1274  }
1275
1276  public void resourceRenamed(Resource resource, String oldName,
1277                              String newName){
1278    for(int i = 0; i < mainTabbedPane.getTabCount(); i++){
1279      if(mainTabbedPane.getTitleAt(i).equals(oldName)){
1280        mainTabbedPane.setTitleAt(i, newName);
1281
1282        return;
1283      }
1284    }
1285  }
1286
1287  /**
1288   * Overridden so we can exit when window is closed
1289   */
1290  protected void processWindowEvent(WindowEvent e) {
1291    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
1292      new ExitGateAction().actionPerformed(null);
1293    }
1294    super.processWindowEvent(e);
1295  }// processWindowEvent(WindowEvent e)
1296
1297  /**
1298   * Returns the listeners map, a map that holds all the listeners that are
1299   * singletons (e.g. the status listener that updates the status bar on the
1300   * main frame or the progress listener that updates the progress bar on the
1301   * main frame).
1302   * The keys used are the class names of the listener interface and the values
1303   * are the actual listeners (e.g "gate.event.StatusListener" -> this).
1304   * The returned map is the actual data member used to store the listeners so
1305   * any changes in this map will be visible to everyone.
1306   */
1307  public static java.util.Map getListeners() {
1308    return listeners;
1309  }
1310
1311  public static java.util.Collection getGuiRoots() {
1312    return guiRoots;
1313  }
1314
1315  /**
1316   * This method will lock all input to the gui by means of a modal dialog.
1317   * If Gate is not currently running in GUI mode this call will be ignored.
1318   * A call to this method while the GUI is locked will cause the GUI to be
1319   * unlocked and then locked again with the new message.
1320   * If a message is provided it will show in the dialog.
1321   * @param message the message to be displayed while the GUI is locked
1322   */
1323  public synchronized static void lockGUI(final String message){
1324    //check whether GUI is up
1325    if(getGuiRoots() == null || getGuiRoots().isEmpty()) return;
1326    //if the GUI is locked unlock it so we can show the new message
1327    unlockGUI();
1328
1329    //build the dialog contents
1330    Object[] options = new Object[]{new JButton(new StopAction())};
1331    JOptionPane pane = new JOptionPane(message, JOptionPane.WARNING_MESSAGE,
1332                                       JOptionPane.DEFAULT_OPTION,
1333                                       null, options, null);
1334
1335    //build the dialog
1336    Component parentComp = (Component)((ArrayList)getGuiRoots()).get(0);
1337    JDialog dialog;
1338    Window parentWindow;
1339    if(parentComp instanceof Window) parentWindow = (Window)parentComp;
1340    else parentWindow = SwingUtilities.getWindowAncestor(parentComp);
1341    if(parentWindow instanceof Frame){
1342      dialog = new JDialog((Frame)parentWindow, "Please wait", true){
1343        protected void processWindowEvent(WindowEvent e) {
1344          if (e.getID() == WindowEvent.WINDOW_CLOSING) {
1345            getToolkit().beep();
1346          }
1347        }
1348      };
1349    }else if(parentWindow instanceof Dialog){
1350      dialog = new JDialog((Dialog)parentWindow, "Please wait", true){
1351        protected void processWindowEvent(WindowEvent e) {
1352          if (e.getID() == WindowEvent.WINDOW_CLOSING) {
1353            getToolkit().beep();
1354          }
1355        }
1356      };
1357    }else{
1358      dialog = new JDialog(JOptionPane.getRootFrame(), "Please wait", true){
1359        protected void processWindowEvent(WindowEvent e) {
1360          if (e.getID() == WindowEvent.WINDOW_CLOSING) {
1361            getToolkit().beep();
1362          }
1363        }
1364      };
1365    }
1366    dialog.getContentPane().setLayout(new BorderLayout());
1367    dialog.getContentPane().add(pane, BorderLayout.CENTER);
1368    dialog.pack();
1369    dialog.setLocationRelativeTo(parentComp);
1370    dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
1371    guiLock = dialog;
1372
1373    //this call needs to return so we'll show the dialog from a different thread
1374    //the Swing thread sounds good for that
1375    SwingUtilities.invokeLater(new Runnable(){
1376      public void run(){
1377        guiLock.show();
1378      }
1379    });
1380
1381    //this call should not return until the dialog is up to ensure proper
1382    //sequentiality for lock - unlock calls
1383    while(!guiLock.isShowing()){
1384      try{
1385        Thread.sleep(100);
1386      }catch(InterruptedException ie){}
1387    }
1388  }
1389
1390  public synchronized static void unlockGUI(){
1391    //check whether GUI is up
1392    if(getGuiRoots() == null || getGuiRoots().isEmpty()) return;
1393
1394    if(guiLock != null) guiLock.hide();
1395    guiLock = null;
1396  }
1397
1398  /** Flag to protect Frame title to be changed */
1399  private boolean titleChangable = false;
1400
1401  public void setTitleChangable(boolean isChangable) {
1402    titleChangable = isChangable;
1403  } // setTitleChangable(boolean isChangable)
1404
1405  /** Override to avoid Protege to change Frame title */
1406  public synchronized void setTitle(String title) {
1407    if(titleChangable) {
1408      super.setTitle(title);
1409    } // if
1410  } // setTitle(String title)
1411
1412
1413
1414  /** Method is used in NewDSAction */
1415  protected DataStore createSerialDataStore() {
1416    DataStore ds = null;
1417
1418    //get the URL (a file in this case)
1419    fileChooser.setDialogTitle("Please create a new empty directory");
1420    fileChooser.setFileSelectionMode(fileChooser.DIRECTORIES_ONLY);
1421    if(fileChooser.showOpenDialog(MainFrame.this) ==
1422                                          fileChooser.APPROVE_OPTION){
1423      try {
1424        URL dsURL = fileChooser.getSelectedFile().toURL();
1425        ds = Factory.createDataStore("gate.persist.SerialDataStore",
1426                                               dsURL.toExternalForm());
1427      } catch(MalformedURLException mue) {
1428        JOptionPane.showMessageDialog(
1429            MainFrame.this, "Invalid location for the datastore\n " +
1430                              mue.toString(),
1431                              "Gate", JOptionPane.ERROR_MESSAGE);
1432      } catch(PersistenceException pe) {
1433        JOptionPane.showMessageDialog(
1434            MainFrame.this, "Datastore creation error!\n " +
1435                              pe.toString(),
1436                              "Gate", JOptionPane.ERROR_MESSAGE);
1437      } // catch
1438    } // if
1439
1440    return ds;
1441  } // createSerialDataStore()
1442
1443  /** Method is used in OpenDSAction */
1444  protected DataStore openSerialDataStore() {
1445    DataStore ds = null;
1446
1447    //get the URL (a file in this case)
1448    fileChooser.setDialogTitle("Select the datastore directory");
1449    fileChooser.setFileSelectionMode(fileChooser.DIRECTORIES_ONLY);
1450    if (fileChooser.showOpenDialog(MainFrame.this) ==
1451                                          fileChooser.APPROVE_OPTION){
1452      try {
1453        URL dsURL = fileChooser.getSelectedFile().toURL();
1454        ds = Factory.openDataStore("gate.persist.SerialDataStore",
1455                                             dsURL.toExternalForm());
1456      } catch(MalformedURLException mue) {
1457        JOptionPane.showMessageDialog(
1458            MainFrame.this, "Invalid location for the datastore\n " +
1459                              mue.toString(),
1460                              "Gate", JOptionPane.ERROR_MESSAGE);
1461      } catch(PersistenceException pe) {
1462        JOptionPane.showMessageDialog(
1463            MainFrame.this, "Datastore opening error!\n " +
1464                              pe.toString(),
1465                              "Gate", JOptionPane.ERROR_MESSAGE);
1466      } // catch
1467    } // if
1468
1469    return ds;
1470  } // openSerialDataStore()
1471
1472
1473/*
1474  synchronized void showWaitDialog() {
1475    Point location = getLocationOnScreen();
1476    location.translate(10,
1477              getHeight() - waitDialog.getHeight() - southBox.getHeight() - 10);
1478    waitDialog.setLocation(location);
1479    waitDialog.showDialog(new Component[]{});
1480  }
1481
1482  synchronized void  hideWaitDialog() {
1483    waitDialog.goAway();
1484  }
1485*/
1486
1487/*
1488  class NewProjectAction extends AbstractAction {
1489    public NewProjectAction(){
1490      super("New Project", new ImageIcon(MainFrame.class.getResource(
1491                                        "/gate/resources/img/newProject.gif")));
1492      putValue(SHORT_DESCRIPTION,"Create a new project");
1493    }
1494    public void actionPerformed(ActionEvent e){
1495      fileChooser.setDialogTitle("Select new project file");
1496      fileChooser.setFileSelectionMode(fileChooser.FILES_ONLY);
1497      if(fileChooser.showOpenDialog(parentFrame) == fileChooser.APPROVE_OPTION){
1498        ProjectData pData = new ProjectData(fileChooser.getSelectedFile(),
1499                                                                  parentFrame);
1500        addProject(pData);
1501      }
1502    }
1503  }
1504*/
1505
1506  /** This class represent an action which brings up the Annot Diff tool*/
1507  class NewAnnotDiffAction extends AbstractAction {
1508    public NewAnnotDiffAction() {
1509      super("Annotation Diff", getIcon("annDiff.gif"));
1510      putValue(SHORT_DESCRIPTION,"Create a new Annotation Diff Tool");
1511    }// NewAnnotDiffAction
1512    public void actionPerformed(ActionEvent e) {
1513      AnnotDiffDialog annotDiffDialog = new AnnotDiffDialog(MainFrame.this);
1514      annotDiffDialog.setTitle("Annotation Diff Tool");
1515      annotDiffDialog.setVisible(true);
1516    }// actionPerformed();
1517  }//class NewAnnotDiffAction
1518
1519  /** This class represent an action which brings up the Corpus Annot Diff tool*/
1520  class NewCorpusAnnotDiffAction extends AbstractAction {
1521    public NewCorpusAnnotDiffAction() {
1522      super("Corpus Annotation Diff", getIcon("annDiff.gif"));
1523      putValue(SHORT_DESCRIPTION,"Create a new Corpus Annotation Diff Tool");
1524    }// NewCorpusAnnotDiffAction
1525    public void actionPerformed(ActionEvent e) {
1526      CorpusAnnotDiffDialog annotDiffDialog =
1527        new CorpusAnnotDiffDialog(MainFrame.this);
1528      annotDiffDialog.setTitle("Corpus Annotation Diff Tool");
1529      annotDiffDialog.setVisible(true);
1530    }// actionPerformed();
1531  }//class NewCorpusAnnotDiffAction
1532
1533  /** This class represent an action which brings up the corpus evaluation tool*/
1534  class NewCorpusEvalAction extends AbstractAction {
1535    public NewCorpusEvalAction() {
1536      super("Default mode");
1537      putValue(SHORT_DESCRIPTION,"Run the Benchmark Tool in its default mode");
1538    }// newCorpusEvalAction
1539
1540    public void actionPerformed(ActionEvent e) {
1541      Runnable runnable = new Runnable(){
1542        public void run(){
1543          JFileChooser chooser = MainFrame.getFileChooser();
1544          chooser.setDialogTitle("Please select a directory which contains " +
1545                                 "the documents to be evaluated");
1546          chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1547          chooser.setMultiSelectionEnabled(false);
1548          int state = chooser.showOpenDialog(MainFrame.this);
1549          File startDir = chooser.getSelectedFile();
1550          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1551            return;
1552
1553          chooser.setDialogTitle("Please select the application that you want to run");
1554          chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1555          state = chooser.showOpenDialog(MainFrame.this);
1556          File testApp = chooser.getSelectedFile();
1557          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1558            return;
1559
1560          //first create the tool and set its parameters
1561          CorpusBenchmarkTool theTool = new CorpusBenchmarkTool();
1562          theTool.setStartDirectory(startDir);
1563          theTool.setApplicationFile(testApp);
1564          theTool.setVerboseMode(
1565            MainFrame.this.verboseModeCorpusEvalToolAction.isVerboseMode());
1566
1567          Out.prln("Please wait while GATE tools are initialised.");
1568          //initialise the tool
1569          theTool.init();
1570          //and execute it
1571          theTool.execute();
1572          theTool.printStatistics();
1573
1574          Out.prln("Overall average precision: " + theTool.getPrecisionAverage());
1575          Out.prln("Overall average recall: " + theTool.getRecallAverage());
1576          Out.prln("Finished!");
1577          theTool.unloadPRs();
1578        }
1579      };
1580      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
1581                                 runnable, "Eval thread");
1582      thread.setPriority(Thread.MIN_PRIORITY);
1583      thread.start();
1584    }// actionPerformed();
1585  }//class NewCorpusEvalAction
1586
1587  /** This class represent an action which brings up the corpus evaluation tool*/
1588  class StoredMarkedCorpusEvalAction extends AbstractAction {
1589    public StoredMarkedCorpusEvalAction() {
1590      super("Human marked against stored processing results");
1591      putValue(SHORT_DESCRIPTION,"Run the Benchmark Tool -stored_clean");
1592    }// newCorpusEvalAction
1593
1594    public void actionPerformed(ActionEvent e) {
1595      Runnable runnable = new Runnable(){
1596        public void run(){
1597          JFileChooser chooser = MainFrame.getFileChooser();
1598          chooser.setDialogTitle("Please select a directory which contains " +
1599                                 "the documents to be evaluated");
1600          chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1601          chooser.setMultiSelectionEnabled(false);
1602          int state = chooser.showOpenDialog(MainFrame.this);
1603          File startDir = chooser.getSelectedFile();
1604          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1605            return;
1606
1607          //first create the tool and set its parameters
1608          CorpusBenchmarkTool theTool = new CorpusBenchmarkTool();
1609          theTool.setStartDirectory(startDir);
1610          theTool.setMarkedStored(true);
1611          theTool.setVerboseMode(
1612            MainFrame.this.verboseModeCorpusEvalToolAction.isVerboseMode());
1613//          theTool.setMarkedDS(
1614//            MainFrame.this.datastoreModeCorpusEvalToolAction.isDatastoreMode());
1615
1616
1617          Out.prln("Evaluating human-marked documents against pre-stored results.");
1618          //initialise the tool
1619          theTool.init();
1620          //and execute it
1621          theTool.execute();
1622          theTool.printStatistics();
1623
1624          Out.prln("Overall average precision: " + theTool.getPrecisionAverage());
1625          Out.prln("Overall average recall: " + theTool.getRecallAverage());
1626          Out.prln("Finished!");
1627          theTool.unloadPRs();
1628        }
1629      };
1630      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
1631                                 runnable, "Eval thread");
1632      thread.setPriority(Thread.MIN_PRIORITY);
1633      thread.start();
1634    }// actionPerformed();
1635  }//class StoredMarkedCorpusEvalActionpusEvalAction
1636
1637  /** This class represent an action which brings up the corpus evaluation tool*/
1638  class CleanMarkedCorpusEvalAction extends AbstractAction {
1639    public CleanMarkedCorpusEvalAction() {
1640      super("Human marked against current processing results");
1641      putValue(SHORT_DESCRIPTION,"Run the Benchmark Tool -marked_clean");
1642    }// newCorpusEvalAction
1643
1644    public void actionPerformed(ActionEvent e) {
1645      Runnable runnable = new Runnable(){
1646        public void run(){
1647          JFileChooser chooser = MainFrame.getFileChooser();
1648          chooser.setDialogTitle("Please select a directory which contains " +
1649                                 "the documents to be evaluated");
1650          chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1651          chooser.setMultiSelectionEnabled(false);
1652          int state = chooser.showOpenDialog(MainFrame.this);
1653          File startDir = chooser.getSelectedFile();
1654          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1655            return;
1656
1657          chooser.setDialogTitle("Please select the application that you want to run");
1658          chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1659          state = chooser.showOpenDialog(MainFrame.this);
1660          File testApp = chooser.getSelectedFile();
1661          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1662            return;
1663
1664          //first create the tool and set its parameters
1665          CorpusBenchmarkTool theTool = new CorpusBenchmarkTool();
1666          theTool.setStartDirectory(startDir);
1667          theTool.setApplicationFile(testApp);
1668          theTool.setMarkedClean(true);
1669          theTool.setVerboseMode(
1670            MainFrame.this.verboseModeCorpusEvalToolAction.isVerboseMode());
1671
1672          Out.prln("Evaluating human-marked documents against current processing results.");
1673          //initialise the tool
1674          theTool.init();
1675          //and execute it
1676          theTool.execute();
1677          theTool.printStatistics();
1678
1679          Out.prln("Overall average precision: " + theTool.getPrecisionAverage());
1680          Out.prln("Overall average recall: " + theTool.getRecallAverage());
1681          Out.prln("Finished!");
1682          theTool.unloadPRs();
1683        }
1684      };
1685      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
1686                                 runnable, "Eval thread");
1687      thread.setPriority(Thread.MIN_PRIORITY);
1688      thread.start();
1689    }// actionPerformed();
1690  }//class CleanMarkedCorpusEvalActionpusEvalAction
1691
1692
1693  /** This class represent an action which brings up the corpus evaluation tool*/
1694  class GenerateStoredCorpusEvalAction extends AbstractAction {
1695    public GenerateStoredCorpusEvalAction() {
1696      super("Store corpus for future evaluation");
1697      putValue(SHORT_DESCRIPTION,"Run the Benchmark Tool -generate");
1698    }// newCorpusEvalAction
1699
1700    public void actionPerformed(ActionEvent e) {
1701      Runnable runnable = new Runnable(){
1702        public void run(){
1703          JFileChooser chooser = MainFrame.getFileChooser();
1704          chooser.setDialogTitle("Please select a directory which contains " +
1705                                 "the documents to be evaluated");
1706          chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1707          chooser.setMultiSelectionEnabled(false);
1708          int state = chooser.showOpenDialog(MainFrame.this);
1709          File startDir = chooser.getSelectedFile();
1710          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1711            return;
1712
1713          chooser.setDialogTitle("Please select the application that you want to run");
1714          chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1715          state = chooser.showOpenDialog(MainFrame.this);
1716          File testApp = chooser.getSelectedFile();
1717          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1718            return;
1719
1720          //first create the tool and set its parameters
1721          CorpusBenchmarkTool theTool = new CorpusBenchmarkTool();
1722          theTool.setStartDirectory(startDir);
1723          theTool.setApplicationFile(testApp);
1724          theTool.setGenerateMode(true);
1725
1726          Out.prln("Processing and storing documents for future evaluation.");
1727          //initialise the tool
1728          theTool.init();
1729          //and execute it
1730          theTool.execute();
1731          theTool.unloadPRs();
1732          Out.prln("Finished!");
1733        }
1734      };
1735      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
1736                                 runnable, "Eval thread");
1737      thread.setPriority(Thread.MIN_PRIORITY);
1738      thread.start();
1739    }// actionPerformed();
1740  }//class GenerateStoredCorpusEvalAction
1741
1742  /** This class represent an action which brings up the corpus evaluation tool*/
1743  class VerboseModeCorpusEvalToolAction extends AbstractAction  {
1744    public VerboseModeCorpusEvalToolAction() {
1745      super("Verbose mode");
1746      putValue(SHORT_DESCRIPTION,"Run the Benchmark Tool in verbose mode");
1747    }// VerboseModeCorpusEvalToolAction
1748
1749    public boolean isVerboseMode() {return verboseMode;}
1750
1751    public void actionPerformed(ActionEvent e) {
1752      if (! (e.getSource() instanceof JCheckBoxMenuItem))
1753        return;
1754      verboseMode = ((JCheckBoxMenuItem)e.getSource()).getState();
1755    }// actionPerformed();
1756    protected boolean verboseMode = false;
1757  }//class f
1758
1759  /** This class represent an action which brings up the corpus evaluation tool*/
1760/*
1761  class DatastoreModeCorpusEvalToolAction extends AbstractAction  {
1762    public DatastoreModeCorpusEvalToolAction() {
1763      super("Use a datastore for human annotated texts");
1764      putValue(SHORT_DESCRIPTION,"Use a datastore for the human annotated texts");
1765    }// DatastoreModeCorpusEvalToolAction
1766
1767    public boolean isDatastoreMode() {return datastoreMode;}
1768
1769    public void actionPerformed(ActionEvent e) {
1770      if (! (e.getSource() instanceof JCheckBoxMenuItem))
1771        return;
1772      datastoreMode = ((JCheckBoxMenuItem)e.getSource()).getState();
1773    }// actionPerformed();
1774    protected boolean datastoreMode = false;
1775  }//class DatastoreModeCorpusEvalToolListener
1776*/
1777
1778  /** This class represent an action which loads ANNIE with default params*/
1779  class LoadANNIEWithDefaultsAction extends AbstractAction
1780                                    implements ANNIEConstants{
1781    public LoadANNIEWithDefaultsAction() {
1782      super("With defaults");
1783    }// NewAnnotDiffAction
1784    public void actionPerformed(ActionEvent e) {
1785      // Loads ANNIE with defaults
1786      Runnable runnable = new Runnable(){
1787        public void run(){
1788          long startTime = System.currentTimeMillis();
1789          FeatureMap params = Factory.newFeatureMap();
1790          try{
1791            //lock the gui
1792            lockGUI("ANNIE is being loaded...");
1793            // Create a serial analyser
1794            SerialAnalyserController sac = (SerialAnalyserController)
1795                Factory.createResource("gate.creole.SerialAnalyserController",
1796                                       Factory.newFeatureMap(),
1797                                       Factory.newFeatureMap(),
1798                                       "ANNIE_" + Gate.genSym());
1799            // Load each PR as defined in gate.creole.ANNIEConstants.PR_NAMES
1800            for(int i = 0; i < PR_NAMES.length; i++){
1801            ProcessingResource pr = (ProcessingResource)
1802                Factory.createResource(PR_NAMES[i], params);
1803              // Add the PR to the sac
1804              sac.add(pr);
1805            }// End for
1806
1807            long endTime = System.currentTimeMillis();
1808            statusChanged("ANNIE loaded in " +
1809                NumberFormat.getInstance().format(
1810                (double)(endTime - startTime) / 1000) + " seconds");
1811          }catch(gate.creole.ResourceInstantiationException ex){
1812            ex.printStackTrace(Err.getPrintWriter());
1813          }finally{
1814            unlockGUI();
1815          }
1816        }// run()
1817      };// End Runnable
1818      Thread thread = new Thread(runnable, "");
1819      thread.setPriority(Thread.MIN_PRIORITY);
1820      thread.start();
1821    }// actionPerformed();
1822  }//class LoadANNIEWithDefaultsAction
1823
1824  /** This class represent an action which loads ANNIE with default params*/
1825  class LoadANNIEWithoutDefaultsAction extends AbstractAction
1826                                    implements ANNIEConstants{
1827    public LoadANNIEWithoutDefaultsAction() {
1828      super("Without defaults");
1829    }// NewAnnotDiffAction
1830    public void actionPerformed(ActionEvent e) {
1831      // Loads ANNIE with defaults
1832      Runnable runnable = new Runnable(){
1833        public void run(){
1834          FeatureMap params = Factory.newFeatureMap();
1835          try{
1836            // Create a serial analyser
1837            SerialAnalyserController sac = (SerialAnalyserController)
1838                Factory.createResource("gate.creole.SerialAnalyserController",
1839                                       Factory.newFeatureMap(),
1840                                       Factory.newFeatureMap(),
1841                                       "ANNIE_" + Gate.genSym());
1842//            NewResourceDialog resourceDialog = new NewResourceDialog(
1843//                                  MainFrame.this, "Resource parameters", true );
1844            // Load each PR as defined in gate.creole.ANNIEConstants.PR_NAMES
1845            for(int i = 0; i < PR_NAMES.length; i++){
1846              //get the params for the Current PR
1847              ResourceData resData = (ResourceData)Gate.getCreoleRegister().
1848                                      get(PR_NAMES[i]);
1849              if(newResourceDialog.show(resData,
1850                                     "Parameters for the new " +
1851                                     resData.getName())){
1852                sac.add((ProcessingResource)Factory.createResource(
1853                          PR_NAMES[i],
1854                          newResourceDialog.getSelectedParameters()));
1855              }else{
1856                //the user got bored and aborted the operation
1857                statusChanged("Loading cancelled! Removing traces...");
1858                Iterator loadedPRsIter = new ArrayList(sac.getPRs()).iterator();
1859                while(loadedPRsIter.hasNext()){
1860                  Factory.deleteResource((ProcessingResource)
1861                                         loadedPRsIter.next());
1862                }
1863                Factory.deleteResource(sac);
1864                statusChanged("Loading cancelled!");
1865                return;
1866              }
1867            }// End for
1868            statusChanged("ANNIE loaded!");
1869          }catch(gate.creole.ResourceInstantiationException ex){
1870            ex.printStackTrace(Err.getPrintWriter());
1871          }// End try
1872        }// run()
1873      };// End Runnable
1874      SwingUtilities.invokeLater(runnable);
1875//      Thread thread = new Thread(runnable, "");
1876//      thread.setPriority(Thread.MIN_PRIORITY);
1877//      thread.start();
1878    }// actionPerformed();
1879  }//class LoadANNIEWithoutDefaultsAction
1880
1881  /** This class represent an action which loads ANNIE without default param*/
1882  class LoadANNIEWithoutDefaultsAction1 extends AbstractAction
1883                                       implements ANNIEConstants {
1884    public LoadANNIEWithoutDefaultsAction1() {
1885      super("Without defaults");
1886    }// NewAnnotDiffAction
1887    public void actionPerformed(ActionEvent e) {
1888      //Load ANNIE without defaults
1889      CreoleRegister reg = Gate.getCreoleRegister();
1890      // Load each PR as defined in gate.creole.ANNIEConstants.PR_NAMES
1891      for(int i = 0; i < PR_NAMES.length; i++){
1892        ResourceData resData = (ResourceData)reg.get(PR_NAMES[i]);
1893        if (resData != null){
1894          NewResourceDialog resourceDialog = new NewResourceDialog(
1895              MainFrame.this, "Resource parameters", true );
1896          resourceDialog.setTitle(
1897                            "Parameters for the new " + resData.getName());
1898          resourceDialog.show(resData);
1899        }else{
1900          Err.prln(PR_NAMES[i] + " not found in Creole register");
1901        }// End if
1902      }// End for
1903      try{
1904        // Create an application at the end.
1905        Factory.createResource("gate.creole.SerialAnalyserController",
1906                               Factory.newFeatureMap(), Factory.newFeatureMap(),
1907                               "ANNIE_" + Gate.genSym());
1908      }catch(gate.creole.ResourceInstantiationException ex){
1909        ex.printStackTrace(Err.getPrintWriter());
1910      }// End try
1911    }// actionPerformed();
1912  }//class LoadANNIEWithoutDefaultsAction
1913
1914  class NewBootStrapAction extends AbstractAction {
1915    public NewBootStrapAction() {
1916      super("BootStrap Wizard", getIcon("annDiff.gif"));
1917    }// NewBootStrapAction
1918    public void actionPerformed(ActionEvent e) {
1919      BootStrapDialog bootStrapDialog = new BootStrapDialog(MainFrame.this);
1920      bootStrapDialog.show();
1921    }// actionPerformed();
1922  }//class NewBootStrapAction
1923
1924
1925  class LoadCreoleRepositoryAction extends AbstractAction {
1926    public LoadCreoleRepositoryAction(){
1927      super("Load a CREOLE repository");
1928      putValue(SHORT_DESCRIPTION,"Load a CREOLE repository");
1929    }
1930
1931    public void actionPerformed(ActionEvent e) {
1932      Box messageBox = Box.createHorizontalBox();
1933      Box leftBox = Box.createVerticalBox();
1934      JTextField urlTextField = new JTextField(20);
1935      leftBox.add(new JLabel("Type an URL"));
1936      leftBox.add(urlTextField);
1937      messageBox.add(leftBox);
1938
1939      messageBox.add(Box.createHorizontalStrut(10));
1940      messageBox.add(new JLabel("or"));
1941      messageBox.add(Box.createHorizontalStrut(10));
1942
1943      class URLfromFileAction extends AbstractAction{
1944        URLfromFileAction(JTextField textField){
1945          super(null, getIcon("loadFile.gif"));
1946          putValue(SHORT_DESCRIPTION,"Click to select a directory");
1947          this.textField = textField;
1948        }
1949
1950        public void actionPerformed(ActionEvent e){
1951          fileChooser.setMultiSelectionEnabled(false);
1952          fileChooser.setFileSelectionMode(fileChooser.DIRECTORIES_ONLY);
1953          fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter());
1954          int result = fileChooser.showOpenDialog(MainFrame.this);
1955          if(result == fileChooser.APPROVE_OPTION){
1956            try{
1957              textField.setText(fileChooser.getSelectedFile().
1958                                            toURL().toExternalForm());
1959            }catch(MalformedURLException mue){
1960              throw new GateRuntimeException(mue.toString());
1961            }
1962          }
1963        }
1964        JTextField textField;
1965      };//class URLfromFileAction extends AbstractAction
1966
1967      Box rightBox = Box.createVerticalBox();
1968      rightBox.add(new JLabel("Select a directory"));
1969      JButton fileBtn = new JButton(new URLfromFileAction(urlTextField));
1970      rightBox.add(fileBtn);
1971      messageBox.add(rightBox);
1972
1973
1974//JOptionPane.showInputDialog(
1975//                            MainFrame.this,
1976//                            "Select type of Datastore",
1977//                            "Gate", JOptionPane.QUESTION_MESSAGE,
1978//                            null, names,
1979//                            names[0]);
1980
1981      int res = JOptionPane.showConfirmDialog(
1982                            MainFrame.this, messageBox,
1983                            "Enter an URL to the directory containig the " +
1984                            "\"creole.xml\" file", JOptionPane.OK_CANCEL_OPTION,
1985                            JOptionPane.QUESTION_MESSAGE, null);
1986      if(res == JOptionPane.OK_OPTION){
1987        try{
1988          URL creoleURL = new URL(urlTextField.getText());
1989          Gate.getCreoleRegister().registerDirectories(creoleURL);
1990        }catch(Exception ex){
1991          JOptionPane.showMessageDialog(
1992              MainFrame.this,
1993              "There was a problem with your selection:\n" +
1994              ex.toString() ,
1995              "Gate", JOptionPane.ERROR_MESSAGE);
1996          ex.printStackTrace(Err.getPrintWriter());
1997        }
1998      }
1999    }
2000  }//class LoadCreoleRepositoryAction extends AbstractAction
2001
2002
2003  class NewResourceAction extends AbstractAction {
2004    /** Used for creation of resource menu item and creation dialog */
2005    ResourceData rData;
2006
2007    public NewResourceAction(ResourceData rData) {
2008      super(rData.getName());
2009      putValue(SHORT_DESCRIPTION, rData.getComment());
2010      this.rData = rData;
2011    } // NewResourceAction(ResourceData rData)
2012
2013    public void actionPerformed(ActionEvent evt) {
2014      Runnable runnable = new Runnable(){
2015        public void run(){
2016          newResourceDialog.setTitle(
2017                              "Parameters for the new " + rData.getName());
2018          newResourceDialog.show(rData);
2019        }
2020      };
2021      SwingUtilities.invokeLater(runnable);
2022    } // actionPerformed
2023  } // class NewResourceAction extends AbstractAction
2024
2025
2026  static class StopAction extends AbstractAction {
2027    public StopAction(){
2028      super(" Stop! ");
2029      putValue(SHORT_DESCRIPTION,"Stops the current action");
2030    }
2031
2032    public boolean isEnabled(){
2033      return Gate.getExecutable() != null;
2034    }
2035
2036    public void actionPerformed(ActionEvent e) {
2037      Executable ex = Gate.getExecutable();
2038      if(ex != null) ex.interrupt();
2039    }
2040  }
2041
2042
2043  class NewDSAction extends AbstractAction {
2044    public NewDSAction(){
2045      super("Create datastore");
2046      putValue(SHORT_DESCRIPTION,"Create a new Datastore");
2047    }
2048
2049    public void actionPerformed(ActionEvent e) {
2050      DataStoreRegister reg = Gate.getDataStoreRegister();
2051      Map dsTypes = reg.getDataStoreClassNames();
2052      HashMap dsTypeByName = new HashMap();
2053      Iterator dsTypesIter = dsTypes.entrySet().iterator();
2054      while(dsTypesIter.hasNext()){
2055        Map.Entry entry = (Map.Entry)dsTypesIter.next();
2056        dsTypeByName.put(entry.getValue(), entry.getKey());
2057      }
2058
2059      if(!dsTypeByName.isEmpty()) {
2060        Object[] names = dsTypeByName.keySet().toArray();
2061        Object answer = JOptionPane.showInputDialog(
2062                            MainFrame.this,
2063                            "Select type of Datastore",
2064                            "Gate", JOptionPane.QUESTION_MESSAGE,
2065                            null, names,
2066                            names[0]);
2067        if(answer != null) {
2068          String className = (String)dsTypeByName.get(answer);
2069          if(className.equals("gate.persist.SerialDataStore")){
2070            createSerialDataStore();
2071          } else if(className.equals("gate.persist.OracleDataStore")) {
2072              JOptionPane.showMessageDialog(
2073                    MainFrame.this, "Oracle datastores can only be created " +
2074                                    "by your Oracle administrator!",
2075                                    "Gate", JOptionPane.ERROR_MESSAGE);
2076          }  else {
2077
2078            throw new UnsupportedOperationException("Unimplemented option!\n"+
2079                                                    "Use a serial datastore");
2080          }
2081        }
2082      } else {
2083        //no ds types
2084        JOptionPane.showMessageDialog(MainFrame.this,
2085                                      "Could not find any registered types " +
2086                                      "of datastores...\n" +
2087                                      "Check your Gate installation!",
2088                                      "Gate", JOptionPane.ERROR_MESSAGE);
2089
2090      }
2091    }
2092  }//class NewDSAction extends AbstractAction
2093
2094  class LoadResourceFromFileAction extends AbstractAction {
2095    public LoadResourceFromFileAction(){
2096      super("Restore application from file");
2097      putValue(SHORT_DESCRIPTION,"Restores a previously saved application");
2098    }
2099
2100    public void actionPerformed(ActionEvent e) {
2101      Runnable runnable = new Runnable(){
2102        public void run(){
2103          fileChooser.setDialogTitle("Select a file for this resource");
2104          fileChooser.setFileSelectionMode(fileChooser.FILES_AND_DIRECTORIES);
2105          if (fileChooser.showOpenDialog(MainFrame.this) ==
2106                                                fileChooser.APPROVE_OPTION){
2107            File file = fileChooser.getSelectedFile();
2108            try{
2109              gate.util.persistence.PersistenceManager.loadObjectFromFile(file);
2110            }catch(ResourceInstantiationException rie){
2111              processFinished();
2112              JOptionPane.showMessageDialog(MainFrame.this,
2113                              "Error!\n"+
2114                               rie.toString(),
2115                               "Gate", JOptionPane.ERROR_MESSAGE);
2116              rie.printStackTrace(Err.getPrintWriter());
2117            }catch(Exception ex){
2118              processFinished();
2119              JOptionPane.showMessageDialog(MainFrame.this,
2120                              "Error!\n"+
2121                               ex.toString(),
2122                               "Gate", JOptionPane.ERROR_MESSAGE);
2123              ex.printStackTrace(Err.getPrintWriter());
2124            }
2125          }
2126        }
2127      };
2128      Thread thread = new Thread(runnable);
2129      thread.setPriority(Thread.MIN_PRIORITY);
2130      thread.start();
2131    }
2132  }
2133
2134  /**
2135   * Closes the view associated to a resource.
2136   * Does not remove the resource from the system, only its view.
2137   */
2138  class CloseViewAction extends AbstractAction {
2139    public CloseViewAction(Handle handle) {
2140      super("Hide this view");
2141      putValue(SHORT_DESCRIPTION, "Hides this view");
2142      this.handle = handle;
2143    }
2144
2145    public void actionPerformed(ActionEvent e) {
2146      mainTabbedPane.remove(handle.getLargeView());
2147      mainTabbedPane.setSelectedIndex(mainTabbedPane.getTabCount() - 1);
2148    }//public void actionPerformed(ActionEvent e)
2149    Handle handle;
2150  }//class CloseViewAction
2151
2152  class RenameResourceAction extends AbstractAction{
2153    RenameResourceAction(TreePath path){
2154      super("Rename");
2155      putValue(SHORT_DESCRIPTION, "Renames the resource");
2156      this.path = path;
2157    }
2158    public void actionPerformed(ActionEvent e) {
2159      resourcesTree.startEditingAtPath(path);
2160    }
2161
2162    TreePath path;
2163  }
2164
2165  class CloseSelectedResourcesAction extends AbstractAction {
2166    public CloseSelectedResourcesAction() {
2167      super("Close all");
2168      putValue(SHORT_DESCRIPTION, "Closes the selected resources");
2169    }
2170
2171    public void actionPerformed(ActionEvent e) {
2172      TreePath[] paths = resourcesTree.getSelectionPaths();
2173      for(int i = 0; i < paths.length; i++){
2174        Object userObject = ((DefaultMutableTreeNode)paths[i].
2175                            getLastPathComponent()).getUserObject();
2176        if(userObject instanceof NameBearerHandle){
2177          ((NameBearerHandle)userObject).getCloseAction().actionPerformed(null);
2178        }
2179      }
2180    }
2181  }
2182
2183
2184  /**
2185   * Closes the view associated to a resource.
2186   * Does not remove the resource from the system, only its view.
2187   */
2188  class ExitGateAction extends AbstractAction {
2189    public ExitGateAction() {
2190      super("Exit GATE");
2191      putValue(SHORT_DESCRIPTION, "Closes the application");
2192    }
2193
2194    public void actionPerformed(ActionEvent e) {
2195      Runnable runnable = new Runnable(){
2196        public void run(){
2197          //save the options
2198          OptionsMap userConfig = Gate.getUserConfig();
2199          if(userConfig.getBoolean(GateConstants.SAVE_OPTIONS_ON_EXIT).
2200             booleanValue()){
2201            //save the window size
2202            Integer width = new Integer(MainFrame.this.getWidth());
2203            Integer height = new Integer(MainFrame.this.getHeight());
2204            userConfig.put(GateConstants.MAIN_FRAME_WIDTH, width);
2205            userConfig.put(GateConstants.MAIN_FRAME_HEIGHT, height);
2206            try{
2207              Gate.writeUserConfig();
2208            }catch(GateException ge){
2209              logArea.getOriginalErr().println("Failed to save config data:");
2210              ge.printStackTrace(logArea.getOriginalErr());
2211            }
2212          }else{
2213            //don't save options on close
2214            //save the option not to save the options
2215            OptionsMap originalUserConfig = Gate.getOriginalUserConfig();
2216            originalUserConfig.put(GateConstants.SAVE_OPTIONS_ON_EXIT,
2217                                   new Boolean(false));
2218            userConfig.clear();
2219            userConfig.putAll(originalUserConfig);
2220            try{
2221              Gate.writeUserConfig();
2222            }catch(GateException ge){
2223              logArea.getOriginalErr().println("Failed to save config data:");
2224              ge.printStackTrace(logArea.getOriginalErr());
2225            }
2226          }
2227
2228          //save the session;
2229          File sessionFile = new File(Gate.getUserSessionFileName());
2230          if(userConfig.getBoolean(GateConstants.SAVE_SESSION_ON_EXIT).
2231             booleanValue()){
2232            //save all the open applications
2233            try{
2234              ArrayList appList = new ArrayList(Gate.getCreoleRegister().
2235                                  getAllInstances("gate.Controller"));
2236              //remove all hidden instances
2237              Iterator appIter = appList.iterator();
2238              while(appIter.hasNext())
2239                if(Gate.getHiddenAttribute(((Controller)appIter.next()).
2240                   getFeatures())) appIter.remove();
2241
2242
2243              gate.util.persistence.PersistenceManager.
2244                                    saveObjectToFile(appList, sessionFile);
2245            }catch(Exception ex){
2246              logArea.getOriginalErr().println("Failed to save session data:");
2247              ex.printStackTrace(logArea.getOriginalErr());
2248            }
2249          }else{
2250            //we don't want to save the session
2251            if(sessionFile.exists()) sessionFile.delete();
2252          }
2253          setVisible(false);
2254          dispose();
2255          System.exit(0);
2256        }//run
2257      };//Runnable
2258      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
2259                                 runnable, "Session loader");
2260      thread.setPriority(Thread.MIN_PRIORITY);
2261      thread.start();
2262    }
2263  }
2264
2265
2266  class OpenDSAction extends AbstractAction {
2267    public OpenDSAction() {
2268      super("Open datastore");
2269      putValue(SHORT_DESCRIPTION,"Open a datastore");
2270    }
2271
2272    public void actionPerformed(ActionEvent e) {
2273      DataStoreRegister reg = Gate.getDataStoreRegister();
2274      Map dsTypes = reg.getDataStoreClassNames();
2275      HashMap dsTypeByName = new HashMap();
2276      Iterator dsTypesIter = dsTypes.entrySet().iterator();
2277      while(dsTypesIter.hasNext()){
2278        Map.Entry entry = (Map.Entry)dsTypesIter.next();
2279        dsTypeByName.put(entry.getValue(), entry.getKey());
2280      }
2281
2282      if(!dsTypeByName.isEmpty()) {
2283        Object[] names = dsTypeByName.keySet().toArray();
2284        Object answer = JOptionPane.showInputDialog(
2285                            MainFrame.this,
2286                            "Select type of Datastore",
2287                            "Gate", JOptionPane.QUESTION_MESSAGE,
2288                            null, names,
2289                            names[0]);
2290        if(answer != null) {
2291          String className = (String)dsTypeByName.get(answer);
2292          if(className.indexOf("SerialDataStore") != -1){
2293            openSerialDataStore();
2294          } else if(className.equals("gate.persist.OracleDataStore") ||
2295                    className.equals("gate.persist.PostgresDataStore")
2296                   ) {
2297              List dbPaths = new ArrayList();
2298              Iterator keyIter = reg.getConfigData().keySet().iterator();
2299              while (keyIter.hasNext()) {
2300                String keyName = (String) keyIter.next();
2301                if (keyName.startsWith("url"))
2302                  dbPaths.add(reg.getConfigData().get(keyName));
2303              }
2304              if (dbPaths.isEmpty())
2305                throw new
2306                  GateRuntimeException("JDBC URL not configured in gate.xml");
2307              //by default make it the first
2308              String storageURL = (String)dbPaths.get(0);
2309              if (dbPaths.size() > 1) {
2310                Object[] paths = dbPaths.toArray();
2311                answer = JOptionPane.showInputDialog(
2312                                    MainFrame.this,
2313                                    "Select a database",
2314                                    "Gate", JOptionPane.QUESTION_MESSAGE,
2315                                    null, paths,
2316                                    paths[0]);
2317                if (answer != null)
2318                  storageURL = (String) answer;
2319                else
2320                  return;
2321              }
2322              DataStore ds = null;
2323              AccessController ac = null;
2324              try {
2325                //1. login the user
2326//                ac = new AccessControllerImpl(storageURL);
2327                ac = Factory.createAccessController(storageURL);
2328                Assert.assertNotNull(ac);
2329                ac.open();
2330
2331                Session mySession = null;
2332                User usr = null;
2333                Group grp = null;
2334                try {
2335                  String userName = "";
2336                  String userPass = "";
2337                  String group = "";
2338
2339                  JPanel listPanel = new JPanel();
2340                  listPanel.setLayout(new BoxLayout(listPanel,BoxLayout.X_AXIS));
2341
2342                  JPanel panel1 = new JPanel();
2343                  panel1.setLayout(new BoxLayout(panel1,BoxLayout.Y_AXIS));
2344                  panel1.add(new JLabel("User name: "));
2345                  panel1.add(new JLabel("Password: "));
2346                  panel1.add(new JLabel("Group: "));
2347
2348                  JPanel panel2 = new JPanel();
2349                  panel2.setLayout(new BoxLayout(panel2,BoxLayout.Y_AXIS));
2350                  JTextField usrField = new JTextField(30);
2351                  panel2.add(usrField);
2352                  JPasswordField pwdField = new JPasswordField(30);
2353                  panel2.add(pwdField);
2354                  JComboBox grpField = new JComboBox(ac.listGroups().toArray());
2355                  grpField.setSelectedIndex(0);
2356                  panel2.add(grpField);
2357
2358                  listPanel.add(panel1);
2359                  listPanel.add(Box.createHorizontalStrut(20));
2360                  listPanel.add(panel2);
2361
2362                  if(OkCancelDialog.showDialog(MainFrame.this.getContentPane(),
2363                                                listPanel,
2364                                                "Please enter login details")){
2365
2366                    userName = usrField.getText();
2367                    userPass = new String(pwdField.getPassword());
2368                    group = (String) grpField.getSelectedItem();
2369
2370                    if(userName.equals("") || userPass.equals("") || group.equals("")) {
2371                      JOptionPane.showMessageDialog(
2372                        MainFrame.this,
2373                        "You must provide non-empty user name, password and group!",
2374                        "Login error",
2375                        JOptionPane.ERROR_MESSAGE
2376                        );
2377                      return;
2378                    }
2379                  }
2380                  else if(OkCancelDialog.userHasPressedCancel) {
2381                      return;
2382                  }
2383
2384                  grp = ac.findGroup(group);
2385                  usr = ac.findUser(userName);
2386                  mySession = ac.login(userName, userPass, grp.getID());
2387
2388                  //save here the user name, pass and group in local gate.xml
2389
2390                } catch (gate.security.SecurityException ex) {
2391                    JOptionPane.showMessageDialog(
2392                      MainFrame.this,
2393                      ex.getMessage(),
2394                      "Login error",
2395                      JOptionPane.ERROR_MESSAGE
2396                      );
2397                  ac.close();
2398                  return;
2399                }
2400
2401                if (! ac.isValidSession(mySession)){
2402                  JOptionPane.showMessageDialog(
2403                    MainFrame.this,
2404                    "Incorrect session obtained. "
2405                      + "Probably there is a problem with the database!",
2406                    "Login error",
2407                    JOptionPane.ERROR_MESSAGE
2408                    );
2409                  ac.close();
2410                  return;
2411                }
2412
2413                //2. open the oracle datastore
2414                ds = Factory.openDataStore(className, storageURL);
2415                //set the session, so all get/adopt/etc work
2416                ds.setSession(mySession);
2417
2418                //3. add the security data for this datastore
2419                //this saves the user and group information, so it can
2420                //be used later when resources are created with certain rights
2421                FeatureMap securityData = Factory.newFeatureMap();
2422                securityData.put("user", usr);
2423                securityData.put("group", grp);
2424                reg.addSecurityData(ds, securityData);
2425              } catch(PersistenceException pe) {
2426                JOptionPane.showMessageDialog(
2427                    MainFrame.this, "Datastore open error!\n " +
2428                                      pe.toString(),
2429                                      "Gate", JOptionPane.ERROR_MESSAGE);
2430              } catch(gate.security.SecurityException se) {
2431                JOptionPane.showMessageDialog(
2432                    MainFrame.this, "User identification error!\n " +
2433                                      se.toString(),
2434                                      "Gate", JOptionPane.ERROR_MESSAGE);
2435                try {
2436                  if (ac != null)
2437                    ac.close();
2438                  if (ds != null)
2439                    ds.close();
2440                } catch (gate.persist.PersistenceException ex) {
2441                  JOptionPane.showMessageDialog(
2442                      MainFrame.this, "Persistence error!\n " +
2443                                        ex.toString(),
2444                                        "Gate", JOptionPane.ERROR_MESSAGE);
2445                }
2446              }
2447
2448          }else{
2449            JOptionPane.showMessageDialog(
2450                MainFrame.this,
2451                "Support for this type of datastores is not implemenented!\n",
2452                "Gate", JOptionPane.ERROR_MESSAGE);
2453          }
2454        }
2455      } else {
2456        //no ds types
2457        JOptionPane.showMessageDialog(MainFrame.this,
2458                                      "Could not find any registered types " +
2459                                      "of datastores...\n" +
2460                                      "Check your Gate installation!",
2461                                      "Gate", JOptionPane.ERROR_MESSAGE);
2462
2463      }
2464    }
2465  }//class OpenDSAction extends AbstractAction
2466
2467  class HelpAboutAction extends AbstractAction {
2468    public HelpAboutAction(){
2469      super("About");
2470    }
2471
2472    public void actionPerformed(ActionEvent e) {
2473      splash.show();
2474    }
2475  }
2476
2477  class HelpUserGuideAction extends AbstractAction {
2478    public HelpUserGuideAction(){
2479      super("User Guide");
2480      putValue(SHORT_DESCRIPTION, "This option needs an internet connection");
2481    }
2482
2483    public void actionPerformed(ActionEvent e) {
2484
2485      Runnable runnable = new Runnable(){
2486        public void run(){
2487          try{
2488            HelpFrame helpFrame = new HelpFrame();
2489            helpFrame.setPage(new URL("http://www.gate.ac.uk/sale/tao/index.html"));
2490            helpFrame.setSize(800, 600);
2491            //center on screen
2492            Dimension frameSize = helpFrame.getSize();
2493            Dimension ownerSize = Toolkit.getDefaultToolkit().getScreenSize();
2494            Point ownerLocation = new Point(0, 0);
2495            helpFrame.setLocation(
2496                      ownerLocation.x + (ownerSize.width - frameSize.width) / 2,
2497                      ownerLocation.y + (ownerSize.height - frameSize.height) / 2);
2498
2499            helpFrame.setVisible(true);
2500          }catch(IOException ioe){
2501            ioe.printStackTrace(Err.getPrintWriter());
2502          }
2503        }
2504      };
2505      Thread thread = new Thread(runnable);
2506      thread.start();
2507    }
2508  }
2509
2510  protected class ResourcesTreeCellRenderer extends DefaultTreeCellRenderer {
2511    public ResourcesTreeCellRenderer() {
2512      setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
2513    }
2514    public Component getTreeCellRendererComponent(JTree tree,
2515                                              Object value,
2516                                              boolean sel,
2517                                              boolean expanded,
2518                                              boolean leaf,
2519                                              int row,
2520                                              boolean hasFocus){
2521      super.getTreeCellRendererComponent(tree, value, sel, expanded,
2522                                         leaf, row, hasFocus);
2523      if(value == resourcesTreeRoot) {
2524        setIcon(MainFrame.getIcon("project.gif"));
2525        setToolTipText("Gate");
2526      } else if(value == applicationsRoot) {
2527        setIcon(MainFrame.getIcon("applications.gif"));
2528        setToolTipText("Gate applications");
2529      } else if(value == languageResourcesRoot) {
2530        setIcon(MainFrame.getIcon("lrs.gif"));
2531        setToolTipText("Language Resources");
2532      } else if(value == processingResourcesRoot) {
2533        setIcon(MainFrame.getIcon("prs.gif"));
2534        setToolTipText("Processing Resources");
2535      } else if(value == datastoresRoot) {
2536        setIcon(MainFrame.getIcon("dss.gif"));
2537        setToolTipText("Gate Datastores");
2538      }else{
2539        //not one of the default root nodes
2540        value = ((DefaultMutableTreeNode)value).getUserObject();
2541        if(value instanceof Handle) {
2542          setIcon(((Handle)value).getIcon());
2543          setText(((Handle)value).getTitle());
2544          setToolTipText(((Handle)value).getTooltipText());
2545        }
2546      }
2547      return this;
2548    }
2549
2550    public Component getTreeCellRendererComponent1(JTree tree,
2551                                              Object value,
2552                                              boolean sel,
2553                                              boolean expanded,
2554                                              boolean leaf,
2555                                              int row,
2556                                              boolean hasFocus) {
2557      super.getTreeCellRendererComponent(tree, value, selected, expanded,
2558                                         leaf, row, hasFocus);
2559      Object handle = ((DefaultMutableTreeNode)value).getUserObject();
2560      if(handle != null && handle instanceof Handle){
2561        setIcon(((Handle)handle).getIcon());
2562        setText(((Handle)handle).getTitle());
2563        setToolTipText(((Handle)handle).getTooltipText());
2564      }
2565      return this;
2566    }
2567  }
2568
2569  protected class ResourcesTreeCellEditor extends DefaultTreeCellEditor {
2570    ResourcesTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer){
2571      super(tree, renderer);
2572    }
2573
2574    /**
2575     * This is the original implementation from the super class with some
2576     * changes (i.e. shorter timer: 500 ms instead of 1200)
2577     */
2578    protected void startEditingTimer() {
2579      if(timer == null) {
2580        timer = new javax.swing.Timer(500, this);
2581        timer.setRepeats(false);
2582      }
2583      timer.start();
2584    }
2585
2586    /**
2587     * This is the original implementation from the super class with some
2588     * changes (i.e. correct discovery of icon)
2589     */
2590    public Component getTreeCellEditorComponent(JTree tree, Object value,
2591                                                boolean isSelected,
2592                                                boolean expanded,
2593                                                boolean leaf, int row) {
2594      Component retValue = super.getTreeCellEditorComponent(tree, value,
2595                                                            isSelected,
2596                                                            expanded,
2597                                                            leaf, row);
2598      //lets find the actual icon
2599      if(renderer != null) {
2600        renderer.getTreeCellRendererComponent(tree, value, isSelected, expanded,
2601                                              leaf, row, false);
2602        editingIcon = renderer.getIcon();
2603      }
2604      return retValue;
2605    }
2606  }//protected class ResourcesTreeCellEditor extends DefaultTreeCellEditor {
2607
2608  protected class ResourcesTreeModel extends DefaultTreeModel {
2609    ResourcesTreeModel(TreeNode root, boolean asksAllowChildren){
2610      super(root, asksAllowChildren);
2611    }
2612
2613    public void valueForPathChanged(TreePath path, Object newValue){
2614      DefaultMutableTreeNode   aNode = (DefaultMutableTreeNode)
2615                                       path.getLastPathComponent();
2616      Object userObject = aNode.getUserObject();
2617      if(userObject instanceof Handle){
2618        Object target = ((Handle)userObject).getTarget();
2619        if(target instanceof Resource){
2620          Gate.getCreoleRegister().setResourceName((Resource)target,
2621                                                   (String)newValue);
2622        }
2623      }
2624      nodeChanged(aNode);
2625    }
2626  }
2627
2628
2629  /**
2630   * Model for the tree representing the resources loaded in the system
2631   */
2632/*
2633  class ResourcesTreeModel extends DefaultTreeModel {
2634    ResourcesTreeModel(TreeNode root){
2635      super(root);
2636    }
2637
2638    public Object getRoot(){
2639      return resourcesTreeRoot;
2640    }
2641
2642    public Object getChild(Object parent,
2643                       int index){
2644      return getChildren(parent).get(index);
2645    }
2646
2647    public int getChildCount(Object parent){
2648      return getChildren(parent).size();
2649    }
2650
2651    public boolean isLeaf(Object node){
2652      return getChildren(node).isEmpty();
2653    }
2654
2655    public int getIndexOfChild(Object parent,
2656                           Object child){
2657      return getChildren(parent).indexOf(child);
2658    }
2659
2660    protected List getChildren(Object parent) {
2661      List result = new ArrayList();
2662      if(parent == resourcesTreeRoot){
2663        result.add(applicationsRoot);
2664        result.add(languageResourcesRoot);
2665        result.add(processingResourcesRoot);
2666        result.add(datastoresRoot);
2667      } else if(parent == applicationsRoot) {
2668//        result.addAll(currentProject.getApplicationsList());
2669      } else if(parent == languageResourcesRoot) {
2670        result.addAll(Gate.getCreoleRegister().getLrInstances());
2671      } else if(parent == processingResourcesRoot) {
2672        result.addAll(Gate.getCreoleRegister().getPrInstances());
2673      } else if(parent == datastoresRoot) {
2674        result.addAll(Gate.getDataStoreRegister());
2675      }
2676      ListIterator iter = result.listIterator();
2677      while(iter.hasNext()) {
2678        Object value = iter.next();
2679        ResourceData rData = (ResourceData)
2680                      Gate.getCreoleRegister().get(value.getClass().getName());
2681        if(rData != null && rData.isPrivate()) iter.remove();
2682      }
2683      return result;
2684    }
2685
2686    public synchronized void removeTreeModelListener(TreeModelListener l) {
2687      if (treeModelListeners != null && treeModelListeners.contains(l)) {
2688        Vector v = (Vector) treeModelListeners.clone();
2689        v.removeElement(l);
2690        treeModelListeners = v;
2691      }
2692    }
2693
2694    public synchronized void addTreeModelListener(TreeModelListener l) {
2695      Vector v = treeModelListeners ==
2696                    null ? new Vector(2) : (Vector) treeModelListeners.clone();
2697      if (!v.contains(l)) {
2698        v.addElement(l);
2699        treeModelListeners = v;
2700      }
2701    }
2702
2703    void treeChanged(){
2704      SwingUtilities.invokeLater(new Runnable(){
2705        public void run() {
2706          fireTreeStructureChanged(new TreeModelEvent(
2707                                        this,new Object[]{resourcesTreeRoot}));
2708        }
2709      });
2710    }
2711
2712    public void valueForPathChanged(TreePath path,
2713                                Object newValue){
2714      fireTreeNodesChanged(new TreeModelEvent(this,path));
2715    }
2716
2717    protected void fireTreeNodesChanged(TreeModelEvent e) {
2718      if (treeModelListeners != null) {
2719        Vector listeners = treeModelListeners;
2720        int count = listeners.size();
2721        for (int i = 0; i < count; i++) {
2722          ((TreeModelListener) listeners.elementAt(i)).treeNodesChanged(e);
2723        }
2724      }
2725    }
2726
2727    protected void fireTreeNodesInserted(TreeModelEvent e) {
2728      if (treeModelListeners != null) {
2729        Vector listeners = treeModelListeners;
2730        int count = listeners.size();
2731        for (int i = 0; i < count; i++) {
2732          ((TreeModelListener) listeners.elementAt(i)).treeNodesInserted(e);
2733        }
2734      }
2735    }
2736
2737    protected void fireTreeNodesRemoved(TreeModelEvent e) {
2738      if (treeModelListeners != null) {
2739        Vector listeners = treeModelListeners;
2740        int count = listeners.size();
2741        for (int i = 0; i < count; i++) {
2742          ((TreeModelListener) listeners.elementAt(i)).treeNodesRemoved(e);
2743        }
2744      }
2745    }
2746
2747    protected void fireTreeStructureChanged(TreeModelEvent e) {
2748      if (treeModelListeners != null) {
2749        Vector listeners = treeModelListeners;
2750        int count = listeners.size();
2751        for (int i = 0; i < count; i++) {
2752          ((TreeModelListener) listeners.elementAt(i)).treeStructureChanged(e);
2753        }
2754      }
2755    }
2756
2757    private transient Vector treeModelListeners;
2758  }
2759*/
2760
2761  class ProgressBarUpdater implements Runnable{
2762    ProgressBarUpdater(int newValue){
2763      value = newValue;
2764    }
2765
2766    public void run(){
2767      if(value == 0) progressBar.setVisible(false);
2768      else progressBar.setVisible(true);
2769      progressBar.setValue(value);
2770    }
2771
2772    int value;
2773  }
2774
2775  class StatusBarUpdater implements Runnable {
2776    StatusBarUpdater(String text){
2777      this.text = text;
2778    }
2779    public void run(){
2780      statusBar.setText(text);
2781    }
2782    String text;
2783  }
2784
2785  /**
2786   * During longer operations it is nice to keep the user entertained so
2787   * (s)he doesn't fall asleep looking at a progress bar that seems have
2788   * stopped. Also there are some operations that do not support progress
2789   * reporting so the progress bar would not work at all so we need a way
2790   * to let the user know that things are happening. We chose for purpose
2791   * to show the user a small cartoon in the form of an animated gif.
2792   * This class handles the diplaying and updating of those cartoons.
2793   */
2794  class CartoonMinder implements Runnable{
2795
2796    CartoonMinder(JPanel targetPanel){
2797      active = false;
2798      dying = false;
2799      this.targetPanel = targetPanel;
2800      imageLabel = new JLabel(getIcon("working.gif"));
2801      imageLabel.setOpaque(false);
2802      imageLabel.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
2803    }
2804
2805    public boolean isActive(){
2806      boolean res;
2807      synchronized(lock){
2808        res = active;
2809      }
2810      return res;
2811    }
2812
2813    public void activate(){
2814      //add the label in the panel
2815      SwingUtilities.invokeLater(new Runnable(){
2816        public void run(){
2817          targetPanel.add(imageLabel);
2818        }
2819      });
2820      //wake the dorment thread
2821      synchronized(lock){
2822        active = true;
2823      }
2824    }
2825
2826    public void deactivate(){
2827      //send the thread to sleep
2828      synchronized(lock){
2829        active = false;
2830      }
2831      //clear the panel
2832      SwingUtilities.invokeLater(new Runnable(){
2833        public void run(){
2834          targetPanel.removeAll();
2835          targetPanel.repaint();
2836        }
2837      });
2838    }
2839
2840    public void dispose(){
2841      synchronized(lock){
2842        dying = true;
2843      }
2844    }
2845
2846    public void run(){
2847      boolean isDying;
2848      synchronized(lock){
2849        isDying = dying;
2850      }
2851      while(!isDying){
2852        boolean isActive;
2853        synchronized(lock){
2854          isActive = active;
2855        }
2856        if(isActive && targetPanel.isVisible()){
2857          SwingUtilities.invokeLater(new Runnable(){
2858            public void run(){
2859//              targetPanel.getParent().validate();
2860//              targetPanel.getParent().repaint();
2861//              ((JComponent)targetPanel.getParent()).paintImmediately(((JComponent)targetPanel.getParent()).getBounds());
2862//              targetPanel.doLayout();
2863
2864//              targetPanel.requestFocus();
2865              targetPanel.getParent().getParent().invalidate();
2866              targetPanel.getParent().getParent().repaint();
2867//              targetPanel.paintImmediately(targetPanel.getBounds());
2868            }
2869          });
2870        }
2871        //sleep
2872        try{
2873          Thread.sleep(300);
2874        }catch(InterruptedException ie){}
2875
2876        synchronized(lock){
2877          isDying = dying;
2878        }
2879      }//while(!isDying)
2880    }
2881
2882    boolean dying;
2883    boolean active;
2884    String lock = "lock";
2885    JPanel targetPanel;
2886    JLabel imageLabel;
2887  }
2888
2889/*
2890  class JGateMenuItem extends JMenuItem {
2891    JGateMenuItem(javax.swing.Action a){
2892      super(a);
2893      this.addMouseListener(new MouseAdapter() {
2894        public void mouseEntered(MouseEvent e) {
2895          oldText = statusBar.getText();
2896          statusChanged((String)getAction().
2897                        getValue(javax.swing.Action.SHORT_DESCRIPTION));
2898        }
2899
2900        public void mouseExited(MouseEvent e) {
2901          statusChanged(oldText);
2902        }
2903      });
2904    }
2905    String oldText;
2906  }
2907
2908  class JGateButton extends JButton {
2909    JGateButton(javax.swing.Action a){
2910      super(a);
2911      this.addMouseListener(new MouseAdapter() {
2912        public void mouseEntered(MouseEvent e) {
2913          oldText = statusBar.getText();
2914          statusChanged((String)getAction().
2915                        getValue(javax.swing.Action.SHORT_DESCRIPTION));
2916        }
2917
2918        public void mouseExited(MouseEvent e) {
2919          statusChanged(oldText);
2920        }
2921      });
2922    }
2923    String oldText;
2924  }
2925*/
2926  class LocaleSelectorMenuItem extends JRadioButtonMenuItem {
2927    public LocaleSelectorMenuItem(Locale locale) {
2928      super(locale.getDisplayName());
2929      me = this;
2930      myLocale = locale;
2931      this.addActionListener(new ActionListener()  {
2932        public void actionPerformed(ActionEvent e) {
2933          Iterator rootIter = MainFrame.getGuiRoots().iterator();
2934          while(rootIter.hasNext()){
2935            Object aRoot = rootIter.next();
2936            if(aRoot instanceof Window){
2937              me.setSelected(((Window)aRoot).getInputContext().
2938                              selectInputMethod(myLocale));
2939            }
2940          }
2941        }
2942      });
2943    }
2944
2945    public LocaleSelectorMenuItem() {
2946      super("System default  >>" +
2947            Locale.getDefault().getDisplayName() + "<<");
2948      me = this;
2949      myLocale = Locale.getDefault();
2950      this.addActionListener(new ActionListener()  {
2951        public void actionPerformed(ActionEvent e) {
2952          Iterator rootIter = MainFrame.getGuiRoots().iterator();
2953          while(rootIter.hasNext()){
2954            Object aRoot = rootIter.next();
2955            if(aRoot instanceof Window){
2956              me.setSelected(((Window)aRoot).getInputContext().
2957                              selectInputMethod(myLocale));
2958            }
2959          }
2960        }
2961      });
2962    }
2963
2964    Locale myLocale;
2965    JRadioButtonMenuItem me;
2966  }////class LocaleSelectorMenuItem extends JRadioButtonMenuItem
2967
2968  /**ontotext.bp
2969   * This class represent an action which brings up the Ontology Editor tool*/
2970  class NewOntologyEditorAction extends AbstractAction {
2971    public NewOntologyEditorAction(){
2972      super("Ontology Editor", getIcon("controller.gif"));
2973      putValue(SHORT_DESCRIPTION,"Start the Ontology Editor");
2974    }// NewAnnotDiffAction
2975
2976    public void actionPerformed(ActionEvent e) {
2977      OntologyEditorImpl editor = new OntologyEditorImpl();
2978      try {
2979        JFrame frame = new JFrame();
2980        editor.init();
2981        frame.setTitle("Ontology Editor");
2982        frame.getContentPane().add(editor);
2983        /*
2984          SET ONTOLOGY LIST AND ONTOLOGY
2985        */
2986        Set ontologies = new HashSet(Gate.getCreoleRegister().getLrInstances(
2987          "gate.creole.ontology.Ontology"));
2988
2989        editor.setOntologyList(new Vector(ontologies));
2990
2991        frame.setSize(editor.SIZE_X,editor.SIZE_Y);
2992        frame.setLocation(editor.POSITION_X,editor.POSITION_Y);
2993        frame.setVisible(true);
2994        editor.visualize();
2995      } catch ( ResourceInstantiationException ex ) {
2996        ex.printStackTrace(Err.getPrintWriter());
2997      }
2998    }// actionPerformed();
2999  }//class NewOntologyEditorAction
3000
3001  /** This class represent an action which brings up the Gazetteer Editor tool*/
3002  class NewGazetteerEditorAction extends AbstractAction {
3003    public NewGazetteerEditorAction(){
3004      super("Gazetteer Editor", getIcon("controller.gif"));
3005      putValue(SHORT_DESCRIPTION,"Start the Gazetteer Editor");
3006    }
3007
3008    public void actionPerformed(ActionEvent e) {
3009      com.ontotext.gate.vr.Gaze editor = new com.ontotext.gate.vr.Gaze();
3010      try {
3011        JFrame frame = new JFrame();
3012        editor.init();
3013        frame.setTitle("Gazetteer Editor");
3014        frame.getContentPane().add(editor);
3015
3016        Set gazetteers = new HashSet(Gate.getCreoleRegister().getLrInstances(
3017          "gate.creole.gazetteer.DefaultGazetteer"));
3018        if (gazetteers == null || gazetteers.isEmpty())
3019          return;
3020        Iterator iter = gazetteers.iterator();
3021        while (iter.hasNext()) {
3022          gate.creole.gazetteer.Gazetteer gaz =
3023            (gate.creole.gazetteer.Gazetteer) iter.next();
3024          if (gaz.getListsURL().toString().endsWith(System.getProperty("gate.slug.gazetteer")))
3025           editor.setTarget(gaz);
3026        }
3027
3028        frame.setSize(editor.SIZE_X,editor.SIZE_Y);
3029        frame.setLocation(editor.POSITION_X,editor.POSITION_Y);
3030        frame.setVisible(true);
3031        editor.setVisible(true);
3032      } catch ( ResourceInstantiationException ex ) {
3033        ex.printStackTrace(Err.getPrintWriter());
3034      }
3035    }// actionPerformed();
3036  }//class NewOntologyEditorAction
3037
3038} // class MainFrame
3039