JAL-4121 Added a NPE check caught in tests. Added --gui to relevant tests.
[jalview.git] / src / jalview / bin / Jalview.java
index 59382fd..7535f60 100755 (executable)
@@ -53,6 +53,7 @@ import java.util.stream.Collectors;
 
 import javax.swing.JDialog;
 import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
 import javax.swing.JOptionPane;
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
@@ -78,6 +79,7 @@ import jalview.gui.Desktop;
 import jalview.gui.PromptUserConfig;
 import jalview.gui.QuitHandler;
 import jalview.gui.QuitHandler.QResponse;
+import jalview.gui.StructureViewerBase;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.BioJsHTMLOutput;
 import jalview.io.DataSourceType;
@@ -444,11 +446,29 @@ public class Jalview
       public void run()
       {
         Console.debug("Running shutdown hook");
+        QuitHandler.startForceQuit();
+        boolean closeExternal = Cache
+                .getDefault("DEFAULT_CLOSE_EXTERNAL_VIEWERS", false)
+                || Cache.getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", false);
+        StructureViewerBase.setQuitClose(closeExternal);
+        if (desktop != null)
+        {
+          for (JInternalFrame frame : Desktop.desktop.getAllFrames())
+          {
+            if (frame instanceof StructureViewerBase)
+            {
+              ((StructureViewerBase) frame).closeViewer(closeExternal);
+            }
+          }
+        }
+
         if (QuitHandler.gotQuitResponse() == QResponse.CANCEL_QUIT)
         {
           // Got to here by a SIGTERM signal.
           // Note we will not actually cancel the quit from here -- it's too
-          // late -- but we can wait for saving files.
+          // late -- but we can wait for saving files and close external viewers
+          // if configured.
+          // Close viewers/Leave viewers open
           Console.debug("Checking for saving files");
           QuitHandler.getQuitResponse(false);
         }
@@ -515,17 +535,17 @@ public class Jalview
         Jalview.exit(null, 0);
       }
 
-      if (bootstrapArgs.contains(Arg.HEADLESS))
+      // new CLI
+      headlessArg = isHeadless(bootstrapArgs);
+      if (headlessArg)
       {
         System.setProperty("java.awt.headless", "true");
-        // new
-        headlessArg = bootstrapArgs.getBoolean(Arg.HEADLESS);
       }
+      // old CLI
       if (aparser.contains("nodisplay") || aparser.contains("nogui")
               || aparser.contains("headless"))
       {
         System.setProperty("java.awt.headless", "true");
-        // old
         headless = true;
       }
       // anything else!
@@ -774,7 +794,17 @@ public class Jalview
     {
       if (headlessArg)
       {
-        Jalview.exit("Successfully completed commands in headless mode", 0);
+        if (argparser.getBoolean(Arg.NOQUIT))
+        {
+          Console.warn(
+                  "Completed " + Arg.HEADLESS.getName() + " commands, but "
+                          + Arg.NOQUIT + " is set so not quitting!");
+        }
+        else
+        {
+          Jalview.exit("Successfully completed commands in headless mode",
+                  0);
+        }
       }
       Console.info("Successfully completed commands");
     }
@@ -1236,7 +1266,12 @@ public class Jalview
     }
     if (!lafSet)
     {
-      setSystemLookAndFeel();
+      // Flatlaf default for everyone!
+      lafSet = setFlatLookAndFeel();
+      if (!lafSet)
+      {
+        setSystemLookAndFeel();
+      }
       if (Platform.isLinux())
       {
         setLinuxLookAndFeel();
@@ -1433,6 +1468,8 @@ public class Jalview
       UIManager.put("TabbedPane.smoothScrolling", true);
       UIManager.put("TabbedPane.tabWidthMode", "compact");
       UIManager.put("TabbedPane.selectedBackground", Color.white);
+      UIManager.put("TabbedPane.background", new Color(236, 236, 236));
+      UIManager.put("TabbedPane.hoverColor", Color.lightGray);
     }
 
     Desktop.setLiveDragMode(Cache.getDefault("FLAT_LIVE_DRAG_MODE", true));
@@ -1470,6 +1507,7 @@ public class Jalview
     return set;
   }
 
+  /*
   private static void showUsage()
   {
     System.out.println(
@@ -1512,6 +1550,7 @@ public class Jalview
                     + "-jvmmemmax=MAXMEMORY\tOnly available with standalone executable jar or jalview.bin.Launcher. Limit maximum heap size (memory) to MAXMEMORY. MAXMEMORY can be specified in bytes, kilobytes(k), megabytes(m), gigabytes(g) or if you're lucky enough, terabytes(t). This defaults to 32g if total physical memory can be detected, or to 8g if total physical memory cannot be detected. See https://www.jalview.org/help/html/memory.html for more details.\n"
                     + "\n~Read documentation in Application or visit https://www.jalview.org for description of Features and Annotations file~\n\n");
   }
+  */
 
   private static void startUsageStats(final Desktop desktop)
   {
@@ -1847,4 +1886,26 @@ public class Jalview
     System.out.println("[TESTOUTPUT] arg "
             + (yes ? a.argString() : a.negateArgString()) + " was set");
   }
+
+  private static boolean isHeadless(BootstrapArgs bootstrapArgs)
+  {
+    if (bootstrapArgs == null)
+    {
+      return false;
+    }
+    boolean isHeadless = false;
+    if (bootstrapArgs.contains(Arg.GUI))
+    {
+      isHeadless = !bootstrapArgs.getBoolean(Arg.GUI);
+    }
+    else if (bootstrapArgs.contains(Arg.HEADLESS))
+    {
+      isHeadless = bootstrapArgs.getBoolean(Arg.HEADLESS);
+    }
+    else if (bootstrapArgs.argsHaveOption(Opt.OUTPUTFILE))
+    {
+      isHeadless = true;
+    }
+    return isHeadless;
+  }
 }