| MainFrame |

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

| MainFrame |