JAL-2083 removed use of reflection for Groovy
[jalview.git] / src / jalview / gui / Desktop.java
index ba7f255..7f36f7f 100644 (file)
@@ -47,6 +47,7 @@ import java.awt.GridLayout;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Toolkit;
+import java.awt.Window;
 import java.awt.datatransfer.Clipboard;
 import java.awt.datatransfer.ClipboardOwner;
 import java.awt.datatransfer.DataFlavor;
@@ -71,7 +72,6 @@ import java.beans.PropertyVetoException;
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.lang.reflect.Constructor;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Hashtable;
@@ -312,7 +312,20 @@ public class Desktop extends jalview.jbgui.GDesktop implements
      */
     instance = this;
     doVamsasClientCheck();
-    doGroovyCheck();
+
+    groovyShell = new JMenuItem();
+    groovyShell.setText(MessageManager.getString("label.groovy_console"));
+    groovyShell.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        groovyShell_actionPerformed();
+      }
+    });
+    toolsMenu.add(groovyShell);
+    groovyShell.setVisible(true);
+
     doConfigureStructurePrefs();
     setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -383,7 +396,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       @Override
       public void mousePressed(MouseEvent evt)
       {
-        if (SwingUtilities.isRightMouseButton(evt))
+        if (evt.isPopupTrigger())
         {
           showPasteMenu(evt.getX(), evt.getY());
         }
@@ -2386,25 +2399,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements
 
   protected JMenuItem groovyShell;
 
-  public void doGroovyCheck()
-  {
-    if (jalview.bin.Cache.groovyJarsPresent())
-    {
-      groovyShell = new JMenuItem();
-      groovyShell.setText(MessageManager.getString("label.groovy_console"));
-      groovyShell.addActionListener(new ActionListener()
-      {
-        @Override
-        public void actionPerformed(ActionEvent e)
-        {
-          groovyShell_actionPerformed();
-        }
-      });
-      toolsMenu.add(groovyShell);
-      groovyShell.setVisible(true);
-    }
-  }
-
   /**
    * Accessor method to quickly get all the AlignmentFrames loaded.
    * 
@@ -2492,36 +2486,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    */
   public void groovyShell_actionPerformed()
   {
-    // use reflection to avoid creating compilation dependency.
-    if (!jalview.bin.Cache.groovyJarsPresent())
-    {
-      throw new Error(
-              MessageManager
-                      .getString("error.implementation_error_cannot_create_groovyshell"));
-    }
     try
     {
-      Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
-              "groovy.ui.Console");
-      Constructor<?> gccons = gcClass.getConstructor();
-      java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
-              new Class[] { String.class, Object.class });
-      java.lang.reflect.Method run = gcClass.getMethod("run");
-      groovyConsole = gccons.newInstance();
-      setvar.invoke(groovyConsole, new Object[] { "Jalview", this });
-      run.invoke(groovyConsole);
-      /*
-       * and rebuild alignframe menus to enable 'Run Groovy'
-       */
-
-      AlignFrame[] alignFrames = getAlignFrames();
-      if (alignFrames != null)
-      {
-        for (AlignFrame af : alignFrames)
-        {
-          af.setGroovyEnabled(true);
-        }
-      }
+      openGroovyConsole();
     } catch (Exception ex)
     {
       jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
@@ -2534,6 +2501,65 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   }
 
   /**
+   * Open the Groovy console
+   */
+  void openGroovyConsole()
+  {
+    groovyConsole = new groovy.ui.Console();
+
+    /*
+     * bind groovy variable 'Jalview' to the Desktop object
+     */
+    groovyConsole.setVariable("Jalview", this);
+
+    /*
+     * start the console
+     */
+    groovyConsole.run();
+
+    /*
+     * Allow only one console at a time, so that the AlignFrame menu option
+     * 'Calculate | Run Groovy script' is unambiguous.
+     * Disable 'new console', and enable 'Run script', when the console is 
+     * opened, and the reverse when it is closed
+     */
+    Window window = (Window) groovyConsole.getFrame();
+    window.addWindowListener(new WindowAdapter()
+    {
+      @Override
+      public void windowClosed(WindowEvent e)
+      {
+        groovyShell.setEnabled(true);
+        enableExecuteGroovy(false);
+      }
+    });
+
+    /*
+     * if we got this far, enable 'Run Groovy' in AlignFrame menus
+     * and disable opening a second console
+     */
+    groovyShell.setEnabled(false);
+    enableExecuteGroovy(true);
+  }
+
+  /**
+   * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
+   * 
+   * @param enabled
+   */
+  public void enableExecuteGroovy(boolean enabled)
+  {
+    AlignFrame[] alignFrames = getAlignFrames();
+    if (alignFrames != null)
+    {
+      for (AlignFrame af : alignFrames)
+      {
+        af.setGroovyEnabled(enabled);
+      }
+    }
+  }
+
+  /**
    * Progress bars managed by the IProgressIndicator method.
    */
   private Hashtable<Long, JPanel> progressBars;
@@ -2929,12 +2955,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    */
   private java.util.concurrent.Semaphore block = new Semaphore(0);
 
-  /*
-   * groovy.ui.Console object - if Groovy jars are present and the 
-   * user has activated the Groovy console. Use via reflection to
-   * avoid compile-time dependency on Groovy libraries.
-   */
-  private static Object groovyConsole;
+  private static groovy.ui.Console groovyConsole;
 
   /**
    * add another dialog thread to the queue
@@ -3164,7 +3185,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     Desktop.currentAlignFrame = currentAlignFrame;
   }
 
-  public Object getGroovyConsole()
+  public static groovy.ui.Console getGroovyConsole()
   {
     return groovyConsole;
   }