rejigged change support to make it (more) reliable
[jalview.git] / src / jalview / gui / Desktop.java
index 3ba50c5..23b18b0 100755 (executable)
@@ -24,6 +24,8 @@ import java.awt.*;
 import java.awt.datatransfer.*;
 import java.awt.dnd.*;
 import java.awt.event.*;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
@@ -40,7 +42,8 @@ import javax.swing.event.MenuEvent;
 import javax.swing.event.MenuListener;
 
 /**
- * DOCUMENT ME!
+ * Jalview Desktop
+ * 
  * 
  * @author $author$
  * @version $Revision$
@@ -48,15 +51,117 @@ import javax.swing.event.MenuListener;
 public class Desktop extends jalview.jbgui.GDesktop implements
         DropTargetListener, ClipboardOwner, IProgressIndicator
 {
-  /** DOCUMENT ME!! */
+
+  private class JalviewChangeSupport implements PropertyChangeListener
+  {
+    @Override
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+      // Handle change events - most are simply routed to other sources
+      changeSupport.firePropertyChange(evt);
+    }
+
+    /**
+     * change listeners are notified of changes to resources so they can update
+     * their state. E.g. - the 'services' property notifies when the available
+     * set of web service endpoints have changed.
+     */
+    private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
+            this);
+
+    /**
+     * @param propertyName
+     * @param listener
+     * @see java.beans.PropertyChangeSupport#addPropertyChangeListener(java.lang.String,
+     *      java.beans.PropertyChangeListener)
+     */
+    public void addJalviewPropertyChangeListener(String propertyName,
+            PropertyChangeListener listener)
+    {
+      changeSupport.addPropertyChangeListener(propertyName, listener);
+    }
+
+    /**
+     * @param listener
+     * @see java.beans.PropertyChangeSupport#addPropertyChangeListener(
+     *      java.beans.PropertyChangeListener)
+     */
+    public void addJalviewPropertyChangeListener(
+            PropertyChangeListener listener)
+    {
+      changeSupport.addPropertyChangeListener(listener);
+    }
+
+    /*
+     * @param propertyName
+     * 
+     * @param oldValue
+     * 
+     * @param newValue
+     * 
+     * @see
+     * java.beans.PropertyChangeSupport#firePropertyChange(java.lang.String,
+     * java.lang.Object, java.lang.Object) public void firePropertyChange(String
+     * propertyName, Object oldValue, Object newValue) {
+     * changeSupport.firePropertyChange(propertyName, oldValue, newValue); }
+     */
+
+    /**
+     * @param propertyName
+     * @param listener
+     * @see java.beans.PropertyChangeSupport#removePropertyChangeListener(java.lang.String,
+     *      java.beans.PropertyChangeListener)
+     */
+    public void removeJalviewPropertyChangeListener(String propertyName,
+            PropertyChangeListener listener)
+    {
+      changeSupport.removePropertyChangeListener(propertyName, listener);
+    }
+
+  }
+
+  private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
+
+  /**
+   * @param listener
+   * @see jalview.gui.Desktop.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
+   */
+  public void addJalviewPropertyChangeListener(
+          PropertyChangeListener listener)
+  {
+    changeSupport.addJalviewPropertyChangeListener(listener);
+  }
+
+  /**
+   * @param propertyName
+   * @param listener
+   * @see jalview.gui.Desktop.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
+   *      java.beans.PropertyChangeListener)
+   */
+  public void addJalviewPropertyChangeListener(String propertyName,
+          PropertyChangeListener listener)
+  {
+    changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
+  }
+
+  /**
+   * @param propertyName
+   * @param listener
+   * @see jalview.gui.Desktop.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
+   *      java.beans.PropertyChangeListener)
+   */
+  public void removeJalviewPropertyChangeListener(String propertyName,
+          PropertyChangeListener listener)
+  {
+    changeSupport.removeJalviewPropertyChangeListener(propertyName,
+            listener);
+  }
+
+  /** Singleton Desktop instance */
   public static Desktop instance;
 
-  // Need to decide if the Memory Usage is to be included in
-  // Next release or not.
   public static MyDesktopPane desktop;
 
-  // public static JDesktopPane desktop;
-
   static int openFrameCount = 0;
 
   static final int xOffset = 30;
@@ -70,84 +175,105 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   public static boolean internalCopy = false;
 
   static int fileLoadingCount = 0;
-  class MyDesktopManager implements DesktopManager {
-         
-          private DesktopManager delegate;
-        
-          public MyDesktopManager(DesktopManager delegate) {
-             this.delegate = delegate;
-          }
-        
-          public void activateFrame(JInternalFrame f) {
-             try {
-                delegate.activateFrame(f);
-             } catch (NullPointerException npe) {
-                 Point p = getMousePosition();
-                 instance.showPasteMenu(p.x,p.y);
-             }
-          }
-
-       public void beginDraggingFrame(JComponent f) {
-               delegate.beginDraggingFrame(f);
-       }
-
-       public void beginResizingFrame(JComponent f, int direction) {
-               delegate.beginResizingFrame(f, direction);
-       }
-
-       public void closeFrame(JInternalFrame f) {
-               delegate.closeFrame(f);
-       }
-
-       public void deactivateFrame(JInternalFrame f) {
-               delegate.deactivateFrame(f);
-       }
-
-       public void deiconifyFrame(JInternalFrame f) {
-               delegate.deiconifyFrame(f);
-       }
-
-       public void dragFrame(JComponent f, int newX, int newY) {
-               delegate.dragFrame(f, newX, newY);
-       }
-
-       public void endDraggingFrame(JComponent f) {
-               delegate.endDraggingFrame(f);
-       }
-
-       public void endResizingFrame(JComponent f) {
-               delegate.endResizingFrame(f);
-       }
-
-       public void iconifyFrame(JInternalFrame f) {
-               delegate.iconifyFrame(f);
-       }
-
-       public void maximizeFrame(JInternalFrame f) {
-               delegate.maximizeFrame(f);
-       }
-
-       public void minimizeFrame(JInternalFrame f) {
-               delegate.minimizeFrame(f);
-       }
-
-       public void openFrame(JInternalFrame f) {
-               delegate.openFrame(f);
-       }
-
-       public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
-                       int newHeight) {
-               delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
-       }
-
-       public void setBoundsForFrame(JComponent f, int newX, int newY,
-                       int newWidth, int newHeight) {
-               delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
-       }
-        
-          // All other methods, simply delegate
-        
-       }
+
+  class MyDesktopManager implements DesktopManager
+  {
+
+    private DesktopManager delegate;
+
+    public MyDesktopManager(DesktopManager delegate)
+    {
+      this.delegate = delegate;
+    }
+
+    public void activateFrame(JInternalFrame f)
+    {
+      try
+      {
+        delegate.activateFrame(f);
+      } catch (NullPointerException npe)
+      {
+        Point p = getMousePosition();
+        instance.showPasteMenu(p.x, p.y);
+      }
+    }
+
+    public void beginDraggingFrame(JComponent f)
+    {
+      delegate.beginDraggingFrame(f);
+    }
+
+    public void beginResizingFrame(JComponent f, int direction)
+    {
+      delegate.beginResizingFrame(f, direction);
+    }
+
+    public void closeFrame(JInternalFrame f)
+    {
+      delegate.closeFrame(f);
+    }
+
+    public void deactivateFrame(JInternalFrame f)
+    {
+      delegate.deactivateFrame(f);
+    }
+
+    public void deiconifyFrame(JInternalFrame f)
+    {
+      delegate.deiconifyFrame(f);
+    }
+
+    public void dragFrame(JComponent f, int newX, int newY)
+    {
+      delegate.dragFrame(f, newX, newY);
+    }
+
+    public void endDraggingFrame(JComponent f)
+    {
+      delegate.endDraggingFrame(f);
+    }
+
+    public void endResizingFrame(JComponent f)
+    {
+      delegate.endResizingFrame(f);
+    }
+
+    public void iconifyFrame(JInternalFrame f)
+    {
+      delegate.iconifyFrame(f);
+    }
+
+    public void maximizeFrame(JInternalFrame f)
+    {
+      delegate.maximizeFrame(f);
+    }
+
+    public void minimizeFrame(JInternalFrame f)
+    {
+      delegate.minimizeFrame(f);
+    }
+
+    public void openFrame(JInternalFrame f)
+    {
+      delegate.openFrame(f);
+    }
+
+    public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
+            int newHeight)
+    {
+      delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
+    }
+
+    public void setBoundsForFrame(JComponent f, int newX, int newY,
+            int newWidth, int newHeight)
+    {
+      delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
+    }
+
+    // All other methods, simply delegate
+
+  }
+
   /**
    * Creates a new Desktop object.
    */
@@ -177,7 +303,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
 
     // This line prevents Windows Look&Feel resizing all new windows to maximum
     // if previous window was maximised
-    desktop.setDesktopManager(new MyDesktopManager(new DefaultDesktopManager()));
+    desktop.setDesktopManager(new MyDesktopManager(
+            new DefaultDesktopManager()));
     Rectangle dims = getLastKnownDimensions("");
     if (dims != null)
     {
@@ -231,7 +358,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       }
     });
 
-    discoverer = new jalview.ws.jws1.Discoverer(); // Only gets started if gui is
     // displayed.
     // Thread off a new instance of the file chooser - this reduces the time it
     // takes to open it later on.
@@ -1752,7 +1878,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
 
     public void paintComponent(Graphics g)
     {
-      if (showMemoryUsage && g != null)
+      if (showMemoryUsage && g != null && df != null)
       {
         if (percentUsage < 20)
           g.setColor(Color.red);
@@ -1965,15 +2091,66 @@ public class Desktop extends jalview.jbgui.GDesktop implements
 
   public void startServiceDiscovery()
   {
-    discoverer.start();
-    
-    try {
-      new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()).start();
+    startServiceDiscovery(false);
+  }
+
+  public void startServiceDiscovery(boolean blocking)
+  {
+    boolean alive = true;
+    Thread t0 = null, t1 = null, t2 = null;
+
+    // todo: changesupport handlers need to be transferred
+    if (discoverer == null)
+    {
+      discoverer = new jalview.ws.jws1.Discoverer();
+      // register PCS handler for desktop.
+      discoverer.addPropertyChangeListener(changeSupport);
+    }
+    if (Cache.getDefault("SHOW_JWS1_SERVICES", true))
+    {
+      (t0 = new Thread(discoverer)).start();
+    }
+
+    try
+    {
+      if (Cache.getDefault("SHOW_ENVISION2_SERVICES", true))
+      {
+        // EnfinEnvision web service menu entries are rebuild every time the
+        // menu is shown, so no changeSupport events are needed.
+        jalview.ws.EnfinEnvision2OneWay.getInstance();
+        (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
+                .start();
+      }
     } catch (Exception e)
     {
-      Cache.log.info("Exception when trying to launch Envision2 workflow discovery.",e);
+      Cache.log
+              .info(
+                      "Exception when trying to launch Envision2 workflow discovery.",
+                      e);
       Cache.log.info(e.getStackTrace());
     }
-    new Thread(jalview.ws.jws2.Jws2Discoverer.getDiscoverer()).start();
+    if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
+    {
+      jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
+              .addPropertyChangeListener(changeSupport);
+      (t2 = new Thread(jalview.ws.jws2.Jws2Discoverer.getDiscoverer()))
+              .start();
+    }
+    if (blocking)
+    {
+      while (alive)
+      {
+        try
+        {
+          Thread.sleep(15);
+        } catch (Exception e)
+        {
+        }
+        alive = (t1 != null && t1.isAlive())
+                || (t2 != null && t2.isAlive())
+                || (t0 != null && t0.isAlive());
+      }
+    }
   }
+
 }