JAL-3487 Splash screen
authorBobHanson <hansonr@stolaf.edu>
Sat, 13 Jun 2020 21:37:52 +0000 (16:37 -0500)
committerBobHanson <hansonr@stolaf.edu>
Sat, 13 Jun 2020 21:37:52 +0000 (16:37 -0500)
- cleaner code, more comments
- adds SwingJS support for 1-ms image finalization
  (using JSToolkit.dispatch instead of invokeLater

src/jalview/gui/SplashScreen.java
swingjs/SwingJS-site.zip
swingjs/timestamp
swingjs/ver/3.2.9/SwingJS-site.zip
swingjs/ver/3.2.9/timestamp

index 0def6e4..bfa714a 100755 (executable)
@@ -68,12 +68,13 @@ public class SplashScreen extends JPanel
 
   private JInternalFrame iframe;
 
-  private Image image;
+  private Image image, logo;
 
-  protected boolean isInteractive = false;
+  protected boolean isStartup = false;
 
   private long oldTextLength = -1;
 
+  private StateHelper helper;
   /*
    * allow click in the initial splash screen to dismiss it
    * immediately (not if opened from About menu)
@@ -83,7 +84,7 @@ public class SplashScreen extends JPanel
     @Override
     public void mousePressed(MouseEvent evt)
     {
-      if (isInteractive)
+      if (isStartup)
       {
         try
         {
@@ -95,84 +96,82 @@ public class SplashScreen extends JPanel
     }
   };
 
-  private Image logo;
-
-  private StateHelper helper;
-
   /**
    * Constructor that displays the splash screen
    * 
-   * @param isTransient
+   * @param isStartup
    *          if true the panel removes itself on click or after a few seconds;
-   *          if false it stays up until closed by the user
+   *          if false it stays up until closed by the user (from Help..About menu)
    */
-  public SplashScreen(boolean isTransient)
+  public SplashScreen(boolean isStartup)
   {
-    this.isInteractive = isTransient;
-
-    getImages();
+    this.isStartup = isStartup;
+    // we must get the image in JavaScript BEFORE starting the helper,
+    // as it will take a 1 ms clock tick to obtain width and height information.
+    image = Toolkit.getDefaultToolkit().createImage(
+            getClass().getResource("/images/Jalview_Logo.png"));
     helper = new StateHelper(this);
     helper.next(STATE_INIT);
   }
 
-  private void getImages()
+  protected void initSplashScreenWindow()
   {
-    URL url = getClass().getResource("/images/Jalview_Logo.png");
-    URL urllogo = getClass()
-            .getResource("/images/Jalview_Logo_small.png");
-    image = Toolkit.getDefaultToolkit().createImage(url);
-    if (!Platform.isJS())
-      logo = Toolkit.getDefaultToolkit().createImage(urllogo);
+    addMouseListener(closer);
+    waitForImages();
+    setLayout(new BorderLayout());
+    iframe = new JInternalFrame();
+    iframe.setFrameIcon(null);
+    iframe.setClosable(true);
+    iframe.setContentPane(this);
+    iframe.setLayer(JLayeredPane.PALETTE_LAYER);  
+    SplashImage splashimg = new SplashImage(image);
+    imgPanel.add(splashimg, BorderLayout.CENTER);
+    add(imgPanel, BorderLayout.NORTH);
+    Desktop.getDesktopPane().add(iframe);
+    refreshText();
   }
 
   /**
-   * ping the jalview version page then create and display the jalview
-   * splashscreen window.
+   * Both Java and JavaScript have to wait for images, but this method will
+   * accomplish nothing for JavaScript. We have already taken care of image
+   * loading with our state loop in JavaScript.
+   * 
    */
-  void initSplashScreenWindow()
+  private void waitForImages()
   {
-    addMouseListener(closer);
-
+    if (Platform.isJS())
+      return;
+    MediaTracker mt = new MediaTracker(this);
     try
     {
-      MediaTracker mt = new MediaTracker(this);
       mt.addImage(image, 0);
-      if (logo != null)
+      logo = Toolkit.getDefaultToolkit().createImage(
+              getClass().getResource("/images/Jalview_Logo_small.png"));
+    } catch (Exception ex)
+    {
+    }
+    if (logo != null)
+    {
+      mt.addImage(logo, 1);
+    }
+    do
+    {
+      try
       {
-        mt.addImage(logo, 1);
-      }
-      do
+        mt.waitForAll();
+      } catch (InterruptedException x)
       {
-        try
-        {
-          mt.waitForAll();
-        } catch (InterruptedException x)
-        {
-        }
-        if (mt.isErrorAny())
-        {
-          System.err.println("Error when loading images!");
-        }
-      } while (!mt.checkAll());
-      if (logo != null)
+      }
+      if (mt.isErrorAny())
       {
-        Desktop.getInstance().setIconImage(logo);
+        System.err.println("Error when loading images!");
+        break;
       }
-    } catch (Exception ex)
+    } while (!mt.checkAll());
+    if (logo != null)
     {
+      Desktop.getInstance().setIconImage(logo);
     }
-    iframe = new JInternalFrame();
-    iframe.setFrameIcon(null);
-    iframe.setClosable(true);
-    this.setLayout(new BorderLayout());
-    iframe.setContentPane(this);
-    iframe.setLayer(JLayeredPane.PALETTE_LAYER);
-    
-    SplashImage splashimg = new SplashImage(image);
-    imgPanel.add(splashimg, BorderLayout.CENTER);
-    add(imgPanel, BorderLayout.NORTH);
-    Desktop.getDesktopPane().add(iframe);
-    refreshText();
   }
 
   /**
@@ -191,10 +190,6 @@ public class SplashScreen extends JPanel
     jtp.setEditable(false);
     jtp.setContentType("text/html");
     jtp.setText("<html>" + newtext + "</html>");
-    
-    
-    System.out.println("Text found: \n"+newtext+"\nEnd of newtext.");
-    
     jtp.addHyperlinkListener(this);
     jtp.setFont(new Font("Verdana", Font.PLAIN, FONT_SIZE));
     jtp.addMouseListener(closer);
@@ -202,16 +197,24 @@ public class SplashScreen extends JPanel
     jtp.setSize(new Dimension(750, 425));
     add(jtp, BorderLayout.CENTER);
     revalidate();
-    iframe.setBounds((Desktop.getInstance().getWidth() - 750) / 2,
-           50, 750,
-            jtp.getHeight() + imgPanel.getHeight());
+    int h = jtp.getHeight() + imgPanel.getHeight();
+    iframe.setBounds(Math.max(0, (iframe.getParent().getWidth() - 750) / 2),
+           Math.max(0,  (iframe.getParent().getHeight() - h)/2), 750, h);
     iframe.validate();
     iframe.setVisible(true);
     return true;
   }
 
-  
-  protected long startTime;
+  protected void closeSplash()
+  {
+    try
+    {
+
+      iframe.setClosed(true);
+    } catch (Exception ex)
+    {
+    }
+  }
 
   /**
    * A simple state machine with just three states: init, loop, and done. Ideal
@@ -219,6 +222,7 @@ public class SplashScreen extends JPanel
    * identically.
    * 
    */
+  @Override
   public boolean stateLoop()
   {
     while (true)
@@ -227,7 +231,6 @@ public class SplashScreen extends JPanel
       {
       case STATE_INIT:
         initSplashScreenWindow();
-        startTime = System.currentTimeMillis() / 1000;
         helper.setState(STATE_LOOP);
         continue;
       case STATE_LOOP:
@@ -240,11 +243,8 @@ public class SplashScreen extends JPanel
         {
           iframe.repaint();
         }
-        if (!isInteractive)
-        {
-          return false;
-        }
-        helper.delayedState(SHOW_FOR_SECS * 1000, STATE_DONE);
+        if (isStartup)
+          helper.delayedState(SHOW_FOR_SECS * 1000, STATE_DONE);
         return true;
       default:
       case STATE_DONE:
@@ -256,18 +256,7 @@ public class SplashScreen extends JPanel
     }
   }
 
-  public void closeSplash()
-  {
-    try
-    {
-
-      iframe.setClosed(true);
-    } catch (Exception ex)
-    {
-    }
-  }
-
-  public class SplashImage extends JPanel
+  private class SplashImage extends JPanel
   {
     Image image;
 
index 2171b13..ec3b91a 100644 (file)
Binary files a/swingjs/SwingJS-site.zip and b/swingjs/SwingJS-site.zip differ
index a5969be..db0ea2c 100644 (file)
@@ -1 +1 @@
-20200612085846 
+20200613163403 
index 2171b13..ec3b91a 100644 (file)
Binary files a/swingjs/ver/3.2.9/SwingJS-site.zip and b/swingjs/ver/3.2.9/SwingJS-site.zip differ
index a5969be..db0ea2c 100644 (file)
@@ -1 +1 @@
-20200612085846 
+20200613163403