JAL-3446 unused imports removed
[jalview.git] / src / jalview / gui / SplashScreen.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Dimension;
26 import java.awt.Font;
27 import java.awt.Graphics;
28 import java.awt.Image;
29 import java.awt.MediaTracker;
30 import java.awt.Toolkit;
31 import java.awt.event.MouseAdapter;
32 import java.awt.event.MouseEvent;
33
34 import javax.swing.JInternalFrame;
35 import javax.swing.JLayeredPane;
36 import javax.swing.JPanel;
37 import javax.swing.JTextPane;
38 import javax.swing.event.HyperlinkEvent;
39 import javax.swing.event.HyperlinkListener;
40
41 import jalview.util.Platform;
42 import javajs.async.SwingJSUtils.StateHelper;
43 import javajs.async.SwingJSUtils.StateMachine;
44
45 /**
46  * DOCUMENT ME!
47  * 
48  * @author $author$
49  * @version $Revision$
50  */
51 @SuppressWarnings("serial")
52 public class SplashScreen extends JPanel
53         implements HyperlinkListener, StateMachine
54 {
55   
56   private static final int STATE_INIT = 0;
57
58   private static final int STATE_LOOP = 1;
59
60   private static final int STATE_DONE = 2;
61
62   private static final int SHOW_FOR_SECS = 5;
63
64   private int FONT_SIZE = (Platform.isJS() ? 14 : 11);
65
66   private JPanel imgPanel = new JPanel(new BorderLayout());
67
68   private JInternalFrame iframe;
69
70   private Image image, logo;
71
72   protected boolean isStartup = false;
73
74   private long oldTextLength = -1;
75
76   private StateHelper helper;
77   /*
78    * allow click in the initial splash screen to dismiss it
79    * immediately (not if opened from About menu)
80    */
81   private MouseAdapter closer = new MouseAdapter()
82   {
83     @Override
84     public void mousePressed(MouseEvent evt)
85     {
86       if (isStartup)
87       {
88         try
89         {
90           closeSplash();
91         } catch (Exception ex)
92         {
93         }
94       }
95     }
96   };
97
98   /**
99    * Constructor that displays the splash screen
100    * 
101    * @param isStartup
102    *          if true the panel removes itself on click or after a few seconds;
103    *          if false it stays up until closed by the user (from Help..About menu)
104    */
105   public SplashScreen(boolean isStartup)
106   {
107     this.isStartup = isStartup;
108     // we must get the image in JavaScript BEFORE starting the helper,
109     // as it will take a 1 ms clock tick to obtain width and height information.
110     image = Toolkit.getDefaultToolkit().createImage(
111             getClass().getResource("/images/Jalview_Logo.png"));
112     helper = new StateHelper(this);
113     helper.next(STATE_INIT);
114   }
115
116   protected void initSplashScreenWindow()
117   {
118     addMouseListener(closer);
119     waitForImages();
120     setLayout(new BorderLayout());
121     iframe = new JInternalFrame();
122     iframe.setFrameIcon(null);
123     iframe.setClosable(true);
124     iframe.setContentPane(this);
125     iframe.setLayer(JLayeredPane.PALETTE_LAYER);  
126     SplashImage splashimg = new SplashImage(image);
127     imgPanel.add(splashimg, BorderLayout.CENTER);
128     add(imgPanel, BorderLayout.NORTH);
129     Desktop.getDesktopPane().add(iframe);
130     refreshText();
131   }
132
133   /**
134    * Both Java and JavaScript have to wait for images, but this method will
135    * accomplish nothing for JavaScript. We have already taken care of image
136    * loading with our state loop in JavaScript.
137    * 
138    */
139   private void waitForImages()
140   {
141     if (Platform.isJS())
142       return;
143     MediaTracker mt = new MediaTracker(this);
144     try
145     {
146       mt.addImage(image, 0);
147       logo = Toolkit.getDefaultToolkit().createImage(
148               getClass().getResource("/images/Jalview_Logo_small.png"));
149     } catch (Exception ex)
150     {
151     }
152     if (logo != null)
153     {
154       mt.addImage(logo, 1);
155     }
156     do
157     {
158       try
159       {
160         mt.waitForAll();
161       } catch (InterruptedException x)
162       {
163       }
164       if (mt.isErrorAny())
165       {
166         System.err.println("Error when loading images!");
167         break;
168       }
169     } while (!mt.checkAll());
170     if (logo != null)
171     {
172       Desktop.getInstance().setIconImage(logo);
173     }
174   }
175
176   /**
177    * update text in author text panel reflecting current version information
178    */
179   protected boolean refreshText()
180   {
181     String newtext = Desktop.getInstance().getAboutMessage();
182     if (oldTextLength == newtext.length())
183     {
184       return false;
185     }
186     oldTextLength = newtext.length();
187     iframe.setVisible(false);
188     JTextPane jtp = new JTextPane();
189     jtp.setEditable(false);
190     jtp.setContentType("text/html");
191     jtp.setText("<html>" + newtext + "</html>");
192     jtp.addHyperlinkListener(this);
193     jtp.setFont(new Font("Verdana", Font.PLAIN, FONT_SIZE));
194     jtp.addMouseListener(closer);
195     jtp.setVisible(true);
196     jtp.setSize(new Dimension(750, 425));
197     add(jtp, BorderLayout.CENTER);
198     revalidate();
199     int h = jtp.getHeight() + imgPanel.getHeight();
200     iframe.setBounds(Math.max(0, (iframe.getParent().getWidth() - 750) / 2),
201            Math.max(0,  (iframe.getParent().getHeight() - h)/2), 750, h);
202     iframe.validate();
203     iframe.setVisible(true);
204     return true;
205   }
206
207   protected void closeSplash()
208   {
209     try
210     {
211
212       iframe.setClosed(true);
213     } catch (Exception ex)
214     {
215     }
216   }
217
218   /**
219    * A simple state machine with just three states: init, loop, and done. Ideal
220    * for a simple while/sleep loop that works in Java and JavaScript
221    * identically.
222    * 
223    */
224   @Override
225   public boolean stateLoop()
226   {
227     while (true)
228     {
229       switch (helper.getState())
230       {
231       case STATE_INIT:
232         initSplashScreenWindow();
233         helper.setState(STATE_LOOP);
234         continue;
235       case STATE_LOOP:
236         if (!isVisible())
237         {
238           helper.setState(STATE_DONE);
239           continue;
240         }
241         if (refreshText())
242         {
243           iframe.repaint();
244         }
245         if (isStartup)
246           helper.delayedState(SHOW_FOR_SECS * 1000, STATE_DONE);
247         return true;
248       default:
249       case STATE_DONE:
250         setVisible(false);
251         closeSplash();
252         Desktop.getInstance().startDialogQueue();
253         return true;
254       }
255     }
256   }
257
258   private class SplashImage extends JPanel
259   {
260     Image image;
261
262     public SplashImage(Image todisplay)
263     {
264       image = todisplay;
265       if (image != null)
266       {
267         setPreferredSize(new Dimension(image.getWidth(this) + 8,
268                 image.getHeight(this)));
269       }
270     }
271
272     @Override
273     public Dimension getPreferredSize()
274     {
275       return new Dimension(image.getWidth(this) + 8, image.getHeight(this));
276     }
277
278     @Override
279     public void paintComponent(Graphics g)
280     {
281       g.setColor(Color.white);
282       g.fillRect(0, 0, getWidth(), getHeight());
283       g.setColor(Color.black);
284
285       if (image != null)
286       {
287         g.drawImage(image, (getWidth() - image.getWidth(this)) / 2,
288                 (getHeight() - image.getHeight(this)) / 2, this);
289       }
290     }
291   }
292
293   @Override
294   public void hyperlinkUpdate(HyperlinkEvent e)
295   {
296     Desktop.hyperlinkUpdate(e);
297
298   }
299 }