Merge branch 'develop' into patch/JAL-4195_cli_eps_export_npe
[jalview.git] / src / jalview / gui / Desktop.java
index 33ba97c..12ff20b 100644 (file)
@@ -536,6 +536,9 @@ public class Desktop extends jalview.jbgui.GDesktop
       setBounds(xPos, yPos, 900, 650);
     }
 
+    // start dialogue queue for single dialogues
+    startDialogQueue();
+
     if (!Platform.isJS())
     /**
      * Java only
@@ -623,6 +626,12 @@ public class Desktop extends jalview.jbgui.GDesktop
       }
     });
     desktop.addMouseListener(ma);
+
+    if (Platform.isJS())
+    {
+      // used for jalviewjsTest
+      jalview.bin.Console.info("JALVIEWJS: CREATED DESKTOP");
+    }
   }
 
   /**
@@ -1069,7 +1078,36 @@ public class Desktop extends jalview.jbgui.GDesktop
 
     setKeyBindings(frame);
 
-    desktop.add(frame);
+    // Since the latest FlatLaf patch, we occasionally have problems showing structureViewer frames...
+    int tries=3;
+    boolean shown=false;
+    Exception last=null;
+    do
+    {
+      try
+      {
+        desktop.add(frame);
+        shown=true;
+      } catch (IllegalArgumentException iaex)
+      {
+        last=iaex;
+        tries--;
+        jalview.bin.Console.info(
+                "Squashed IllegalArgument Exception (" + tries + " left) for "+frame.getTitle(),
+                iaex);
+        try
+        {
+          Thread.sleep(5);
+        } catch (InterruptedException iex)
+        {
+        }
+        ;
+      }
+    } while (!shown && tries > 0);
+    if (!shown)
+    {
+      jalview.bin.Console.error("Serious Problem whilst showing window "+frame.getTitle(),last);
+    }
 
     windowMenu.add(menuItem);
 
@@ -3051,7 +3089,7 @@ public class Desktop extends jalview.jbgui.GDesktop
   /**
    * pause the queue
    */
-  private java.util.concurrent.Semaphore block = new Semaphore(0);
+  private Semaphore block = new Semaphore(0);
 
   private static groovy.ui.Console groovyConsole;
 
@@ -3069,12 +3107,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       {
         if (dialogPause)
         {
-          try
-          {
-            block.acquire();
-          } catch (InterruptedException x)
-          {
-          }
+          acquireDialogQueue();
         }
         if (instance == null)
         {
@@ -3092,12 +3125,41 @@ public class Desktop extends jalview.jbgui.GDesktop
     });
   }
 
+  private boolean dialogQueueStarted = false;
+
   public void startDialogQueue()
   {
+    if (dialogQueueStarted)
+    {
+      return;
+    }
     // set the flag so we don't pause waiting for another permit and semaphore
     // the current task to begin
-    dialogPause = false;
+    releaseDialogQueue();
+    dialogQueueStarted = true;
+  }
+
+  public void acquireDialogQueue()
+  {
+    try
+    {
+      block.acquire();
+      dialogPause = true;
+    } catch (InterruptedException e)
+    {
+      jalview.bin.Console.debug("Interruption when acquiring DialogueQueue",
+              e);
+    }
+  }
+
+  public void releaseDialogQueue()
+  {
+    if (!dialogPause)
+    {
+      return;
+    }
     block.release();
+    dialogPause = false;
   }
 
   /**
@@ -3132,10 +3194,14 @@ public class Desktop extends jalview.jbgui.GDesktop
     String title = "View of desktop";
     ImageExporter exporter = new ImageExporter(writer, null, TYPE.EPS,
             title);
-    try {
+    try
+    {
       exporter.doExport(of, this, width, height, title);
-    } catch (ImageOutputException ioex) {
-      jalview.bin.Console.error("Unexpected error whilst writing Jalview desktop snapshot as EPS",ioex);
+    } catch (ImageOutputException ioex)
+    {
+      jalview.bin.Console.error(
+              "Unexpected error whilst writing Jalview desktop snapshot as EPS",
+              ioex);
     }
   }
 
@@ -3582,11 +3648,26 @@ public class Desktop extends jalview.jbgui.GDesktop
    */
   public static void closeDesktop()
   {
-    if (Desktop.instance != null) {
+    if (Desktop.instance != null)
+    {
       Desktop.instance.closeAll_actionPerformed(null);
       Desktop.instance.setVisible(false);
-      Desktop.instance.dispose();
+      Desktop us = Desktop.instance;
       Desktop.instance = null;
+      // call dispose in a separate thread - try to avoid indirect deadlocks
+      new Thread(new Runnable() {
+        @Override
+        public void run()
+        {
+          ExecutorService dex = us.dialogExecutor;
+          if (dex!=null) {
+            dex.shutdownNow();
+            us.dialogExecutor=null;
+            us.block.drainPermits();
+          }
+          us.dispose();
+        }
+      }).start();
     }
   }