JAL-3253 jalview.bin.Instance handles all singleton instances -
[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 jalview.bin.Instance;
24 import jalview.util.Platform;
25
26 import java.awt.BorderLayout;
27 import java.awt.Color;
28 import java.awt.Component;
29 import java.awt.Dimension;
30 import java.awt.Font;
31 import java.awt.Graphics;
32 import java.awt.Image;
33 import java.awt.MediaTracker;
34 import java.awt.event.MouseAdapter;
35 import java.awt.event.MouseEvent;
36
37 import javax.swing.JInternalFrame;
38 import javax.swing.JLabel;
39 import javax.swing.JLayeredPane;
40 import javax.swing.JPanel;
41 import javax.swing.JTextPane;
42 import javax.swing.event.HyperlinkEvent;
43 import javax.swing.event.HyperlinkListener;
44
45 /**
46  * DOCUMENT ME!
47  * 
48  * @author $author$
49  * @version $Revision$
50  */
51 public class SplashScreen extends JPanel
52         implements Runnable, HyperlinkListener
53 {
54   boolean visible = true;
55
56   JPanel iconimg = new JPanel(new BorderLayout());
57
58   /**
59    * either text area in javascript or in java text pane
60    */
61   Component authlist;
62
63   JInternalFrame iframe;
64
65   Image image;
66
67   int fontSize = 11;
68
69   int yoffset = 30;
70
71   /**
72    * Creates a new SplashScreen object.
73    */
74   public SplashScreen()
75   {
76     this(false);
77   }
78
79   private boolean interactiveDialog = false;
80
81   /**
82    * 
83    * @param interactive
84    *          if true - an internal dialog is opened rather than a free-floating
85    *          splash screen
86    */
87   public SplashScreen(boolean interactive)
88   {
89     this.interactiveDialog = interactive;
90     // show a splashscreen that will disapper
91     if (Platform.isJS()) // BH 2019
92     {
93       authlist = new JLabel("");
94       run();
95     }
96     else
97     {
98       /**
99        * Java only
100        * 
101        * @j2sIgnore
102        */
103       {
104         authlist = new JTextPane();
105         Thread t = new Thread(this);
106         t.start();
107       }
108     }
109
110   }
111
112   MouseAdapter closer = new MouseAdapter()
113   {
114     @Override
115     public void mousePressed(MouseEvent evt)
116     {
117       try
118       {
119         if (!interactiveDialog)
120         {
121           visible = false;
122           closeSplash();
123         }
124       } catch (Exception ex)
125       {
126       }
127     }
128   };
129
130   /**
131    * ping the jalview version page then create and display the jalview
132    * splashscreen window.
133    */
134   void initSplashScreenWindow()
135   {
136     addMouseListener(closer);
137     try
138     {
139       java.net.URL url = getClass().getResource("/images/Jalview_Logo.png");
140       java.net.URL urllogo = getClass()
141               .getResource("/images/Jalview_Logo_small.png");
142
143       if (!Platform.isJS() && url != null)
144       {
145         image = java.awt.Toolkit.getDefaultToolkit().createImage(url);
146         Image logo = java.awt.Toolkit.getDefaultToolkit()
147                 .createImage(urllogo);
148         MediaTracker mt = new MediaTracker(this);
149         mt.addImage(image, 0);
150         mt.addImage(logo, 1);
151         do
152         {
153           try
154           {
155             mt.waitForAll();
156           } catch (InterruptedException x)
157           {
158           }
159           if (mt.isErrorAny())
160           {
161             System.err.println("Error when loading images!");
162           }
163         } while (!mt.checkAll());
164         Instance.getDesktop().setIconImage(logo);
165       }
166     } catch (Exception ex)
167     {
168     }
169
170     iframe = new JInternalFrame();
171     iframe.setFrameIcon(null);
172     iframe.setClosable(interactiveDialog);
173     this.setLayout(new BorderLayout());
174     iframe.setContentPane(this);
175     iframe.setLayer(JLayeredPane.PALETTE_LAYER);
176     if (Platform.isJS())
177     {
178       // ignore in JavaScript
179     }
180     else
181     /**
182      * Java only
183      * 
184      * @j2sIgnore
185      */
186     {
187       ((JTextPane) authlist).setEditable(false);
188
189       SplashImage splashimg = new SplashImage(image);
190       iconimg.add(splashimg, BorderLayout.CENTER);
191       add(iconimg, BorderLayout.NORTH);
192     }
193     add(authlist, BorderLayout.CENTER);
194     authlist.addMouseListener(closer);
195     Desktop.getDesktopPane().add(iframe);
196     refreshText();
197   }
198
199   long oldtext = -1;
200
201   /**
202    * update text in author text panel reflecting current version information
203    */
204   @SuppressWarnings("unused")
205   protected boolean refreshText()
206   {
207     String newtext = Instance.getDesktop().getAboutMessage(true).toString();
208     // System.err.println("Text found: \n"+newtext+"\nEnd of newtext.");
209     if (oldtext != newtext.length())
210     {
211       iframe.setVisible(false);
212       oldtext = newtext.length();
213       if (Platform.isJS()) // BH 2019
214       {
215         authlist = new JLabel(
216                 "<html><br/><br/><img src=\"swingjs/j2s/images/Jalview_Logo.png\"/><br/>"
217                         + newtext);
218         ((JLabel) authlist).setOpaque(true);
219         ((JLabel) authlist).setBackground(Color.white);
220       }
221       else
222       /**
223        * Java only
224        * 
225        * @j2sIgnore
226        */
227       {
228         authlist = new JTextPane();
229         ((JTextPane) authlist).setEditable(false);
230         ((JTextPane) authlist).setContentType("text/html");
231         ((JTextPane) authlist).setText(newtext);
232         ((JTextPane) authlist).addHyperlinkListener(this);
233       }
234       authlist.addMouseListener(closer);
235
236       authlist.setVisible(true);
237       authlist.setSize(new Dimension(750, 375));
238       add(authlist, BorderLayout.CENTER);
239       revalidate();
240       iframe.setBounds((Instance.getDesktop().getWidth() - 750) / 2,
241               (Instance.getDesktop().getHeight() - 375) / 2, 750,
242               authlist.getHeight() + iconimg.getHeight());
243       iframe.validate();
244       iframe.setVisible(true);
245       return true;
246     }
247     return false;
248   }
249
250   /**
251    * Create splash screen, display it and clear it off again.
252    */
253   @Override
254   public void run()
255   {
256     initSplashScreenWindow();
257
258     long startTime = System.currentTimeMillis() / 1000;
259
260     while (visible)
261     {
262       iframe.repaint();
263       try
264       {
265         Thread.sleep(500);
266       } catch (Exception ex)
267       {
268       }
269
270       if (!interactiveDialog
271               && ((System.currentTimeMillis() / 1000) - startTime) > 5)
272       {
273         visible = false;
274       }
275
276       if (visible && refreshText())
277       {
278         // if (interactiveDialog) {
279         iframe.repaint();
280         // } else {
281         // iframe.repaint();
282         // };
283       }
284       if (interactiveDialog)
285       {
286         return;
287       }
288     }
289
290     closeSplash();
291     Instance.getDesktop().startDialogQueue();
292   }
293
294   /**
295    * DOCUMENT ME!
296    */
297   public void closeSplash()
298   {
299     try
300     {
301
302       iframe.setClosed(true);
303     } catch (Exception ex)
304     {
305     }
306   }
307
308   public class SplashImage extends JPanel
309   {
310     Image image;
311
312     public SplashImage(Image todisplay)
313     {
314       image = todisplay;
315       if (image != null)
316       {
317         setPreferredSize(new Dimension(image.getWidth(this) + 8,
318                 image.getHeight(this)));
319       }
320     }
321
322     @Override
323     public Dimension getPreferredSize()
324     {
325       return new Dimension(image.getWidth(this) + 8, image.getHeight(this));
326     }
327
328     @Override
329     public void paintComponent(Graphics g)
330     {
331       g.setColor(Color.white);
332       g.fillRect(0, 0, getWidth(), getHeight());
333       g.setColor(Color.black);
334       g.setFont(new Font("Verdana", Font.BOLD, fontSize + 6));
335
336       if (image != null)
337       {
338         g.drawImage(image, (getWidth() - image.getWidth(this)) / 2,
339                 (getHeight() - image.getHeight(this)) / 2, this);
340       }
341     }
342     /*
343      * int y = yoffset;
344      * 
345      * g.drawString("Jalview " + jalview.bin.Cache.getProperty("VERSION"), 50,
346      * y);
347      * 
348      * FontMetrics fm = g.getFontMetrics(); int vwidth =
349      * fm.stringWidth("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
350      * g.setFont(new Font("Verdana", Font.BOLD, fontSize + 2)); g.drawString(
351      * "Last updated: " + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"),
352      * 50 + vwidth + 5, y); if (jalview.bin.Cache.getDefault("LATEST_VERSION",
353      * "Checking").equals( "Checking")) { // Displayed when code version and
354      * jnlp version do not match g.drawString("...Checking latest version...",
355      * 50, y += fontSize + 10); y += 5; g.setColor(Color.black); } else if
356      * (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
357      * .equals(jalview.bin.Cache.getProperty("VERSION"))) { if
358      * (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
359      * .indexOf("automated build") == -1) { // Displayed when code version and
360      * jnlp version do not match and code // version is not a development build
361      * g.setColor(Color.red); } g.drawString( "!! Jalview version " +
362      * jalview.bin.Cache.getDefault("LATEST_VERSION", "..Checking..") +
363      * " is available for download from "
364      * +jalview.bin.Cache.getDefault("www.jalview.org"
365      * ,"http://www.jalview.org")+" !!", 50, y += fontSize + 10); y += 5;
366      * g.setColor(Color.black); }
367      * 
368      * g.setFont(new Font("Verdana", Font.BOLD, fontSize)); g.drawString(
369      * "Authors: Jim Procter, Andrew Waterhouse, Michele Clamp, James Cuff, Steve Searle,"
370      * , 50, y += fontSize + 4); g.drawString("David Martin & Geoff Barton.",
371      * 60, y += fontSize + 4); g.drawString(
372      * "Development managed by The Barton Group, University of Dundee.", 50, y
373      * += fontSize + 4); g.drawString("If  you use Jalview, please cite: ", 50,
374      * y += fontSize + 4); g.drawString(
375      * "Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
376      * , 50, y += fontSize + 4); g.drawString(
377      * "Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
378      * , 50, y += fontSize + 4);
379      * g.drawString("Bioinformatics doi: 10.1093/bioinformatics/btp033", 50, y
380      * += fontSize + 4); }
381      */
382   }
383
384   @Override
385   public void hyperlinkUpdate(HyperlinkEvent e)
386   {
387     Desktop.hyperlinkUpdate(e);
388
389   }
390 }