JAL-2320 thread to close Chimera viewer panel if Chimera shut down features/JAL-2320_closeChimeraAction
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 10 Nov 2016 11:03:52 +0000 (11:03 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 10 Nov 2016 11:03:52 +0000 (11:03 +0000)
src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java

index fdcf34f..1f9ec64 100644 (file)
@@ -348,6 +348,8 @@ public class ChimeraManager
       sendChimeraCommand("stop really", false);
       try
       {
+        // TODO is this too violent? could it force close the process
+        // before it has done an orderly shutdown?
         chimera.destroy();
       } catch (Exception ex)
       {
@@ -854,4 +856,9 @@ public class ChimeraManager
   {
     return busy;
   }
+
+  public Process getChimeraProcess()
+  {
+    return chimera;
+  }
 }
index 7ba9186..501e345 100644 (file)
@@ -23,6 +23,7 @@ package jalview.ext.rbvi.chimera;
 import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureRenderer;
 import jalview.api.SequenceRenderer;
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
@@ -110,6 +111,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    */
   private long loadNotifiesHandled = 0;
 
+  private Thread chimeraMonitor;
+
   /**
    * Open a PDB structure file in Chimera and set up mappings from Jalview.
    * 
@@ -195,8 +198,38 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
           String protocol)
   {
     super(ssm, pdbentry, sequenceIs, chains, protocol);
-    viewer = new ChimeraManager(
-            new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true));
+    viewer = new ChimeraManager(new StructureManager(true));
+  }
+
+  /**
+   * Starts a thread that waits for the Chimera process to finish, so that we
+   * can then close the associated resources. This avoids leaving orphaned
+   * Chimera viewer panels in Jalview if the user closes Chimera.
+   */
+  protected void startChimeraProcessMonitor()
+  {
+    final Process p = viewer.getChimeraProcess();
+    chimeraMonitor = new Thread(new Runnable()
+    {
+
+      @Override
+      public void run()
+      {
+        try
+        {
+          p.waitFor();
+          JalviewStructureDisplayI display = getViewer();
+          if (display != null)
+          {
+            display.closeViewer(false);
+          }
+        } catch (InterruptedException e)
+        {
+          // exit thread if Chimera Viewer is closed in Jalview
+        }
+      }
+    });
+    chimeraMonitor.start();
   }
 
   /**
@@ -281,6 +314,10 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     lastCommand = null;
     viewer = null;
 
+    if (chimeraMonitor != null)
+    {
+      chimeraMonitor.interrupt();
+    }
     releaseUIResources();
   }
 
@@ -561,23 +598,29 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   /**
    * Launch Chimera, unless an instance linked to this object is already
-   * running. Returns true if chimera is successfully launched, or already
+   * running. Returns true if Chimera is successfully launched, or already
    * running, else false.
    * 
    * @return
    */
   public boolean launchChimera()
   {
-    if (!viewer.isChimeraLaunched())
-    {
-      return viewer.launchChimera(StructureManager.getChimeraPaths());
-    }
     if (viewer.isChimeraLaunched())
     {
       return true;
     }
-    log("Failed to launch Chimera!");
-    return false;
+
+    boolean launched = viewer.launchChimera(StructureManager
+            .getChimeraPaths());
+    if (launched)
+    {
+      startChimeraProcessMonitor();
+    }
+    else
+    {
+      log("Failed to launch Chimera!");
+    }
+    return launched;
   }
 
   /**