2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Dimension;
28 import java.awt.Graphics;
29 import java.awt.Image;
30 import java.awt.MediaTracker;
31 import java.awt.event.MouseAdapter;
32 import java.awt.event.MouseEvent;
34 import javax.swing.JInternalFrame;
35 import javax.swing.JLabel;
36 import javax.swing.JLayeredPane;
37 import javax.swing.JPanel;
38 import javax.swing.JTextPane;
39 import javax.swing.event.HyperlinkEvent;
40 import javax.swing.event.HyperlinkListener;
42 import jalview.util.ChannelProperties;
43 import jalview.util.Platform;
45 import javajs.async.SwingJSUtils.StateHelper;
46 import javajs.async.SwingJSUtils.StateMachine;
54 @SuppressWarnings("serial")
55 public class SplashScreen extends JPanel
56 implements HyperlinkListener, StateMachine
59 private static final int STATE_INIT = 0;
61 private static final int STATE_LOOP = 1;
63 private static final int STATE_DONE = 2;
64 private static final int SHOW_FOR_SECS = 5;
66 private static final int FONT_SIZE = (Platform.isJS() ? 14 : 11);
68 private boolean visible = true;
70 private JPanel iconimg = new JPanel(new BorderLayout());
72 // could change fg, bg, font later to use ChannelProperties (these are not
73 // actually being used!)
74 private static Color bg = Color.WHITE;
76 private static Color fg = Color.BLACK;
78 private static Font font = new Font("SansSerif", Font.PLAIN, FONT_SIZE);
80 private JPanel imgPanel = new JPanel(new BorderLayout());
83 * as JTextPane in Java, JLabel in javascript
85 private Component splashText;
87 private JInternalFrame iframe;
89 private Image image, logo;
91 private boolean transientDialog = false;
93 private long oldTextLength = -1;
95 private StateHelper helper;
96 public static int logoSize = 32;
99 * allow click in the initial splash screen to dismiss it
100 * immediately (not if opened from About menu)
102 private MouseAdapter closer = new MouseAdapter()
105 public void mousePressed(MouseEvent evt)
112 } catch (Exception ex)
120 * Constructor that displays the splash screen
123 * if true the panel removes itself on click or after a few seconds;
124 * if false it stays up until closed by the user (from Help..About menu)
126 public SplashScreen(boolean isStartup)
128 this.transientDialog = isStartup;
129 // we must get the image in JavaScript BEFORE starting the helper,
130 // as it will take a 1 ms clock tick to obtain width and height information.
131 image = ChannelProperties.getImage("banner");
132 logo = ChannelProperties.getImage("logo.48");
133 font = new Font("SansSerif", Font.PLAIN, FONT_SIZE);
134 helper = new StateHelper(this);
135 helper.next(STATE_INIT);
138 protected void initSplashScreenWindow()
140 addMouseListener(closer);
142 setLayout(new BorderLayout());
143 iframe = new JInternalFrame();
144 iframe.setFrameIcon(null);
145 iframe.setClosable(true);
146 iframe.setContentPane(this);
147 iframe.setLayer(JLayeredPane.PALETTE_LAYER);
148 SplashImage splashimg = new SplashImage(image);
149 imgPanel.add(splashimg, BorderLayout.CENTER);
150 add(imgPanel, BorderLayout.NORTH);
151 Desktop.getDesktopPane().add(iframe);
156 * Both Java and JavaScript have to wait for images, but this method will
157 * accomplish nothing for JavaScript. We have already taken care of image
158 * loading with our state loop in JavaScript.
161 private void waitForImages()
165 MediaTracker mt = new MediaTracker(this);
166 mt.addImage(image, 0);
167 mt.addImage(logo, 1);
173 } catch (InterruptedException x)
178 System.err.println("Error when loading images!");
181 } while (!mt.checkAll());
184 Desktop.getInstance().setIconImage(logo);
187 this.setBackground(bg);
188 this.setForeground(fg);
193 * update text in author text panel reflecting current version information
195 protected boolean refreshText()
197 String newtext = Desktop.getInstance().getAboutMessage();
198 // System.err.println("Text found: \n"+newtext+"\nEnd of newtext.");
199 if (oldTextLength == newtext.length())
204 iframe.setVisible(false);
205 oldTextLength = newtext.length();
206 if (Platform.isJS()) // BH 2019
209 * SwingJS doesn't have HTMLEditorKit, required for a JTextPane
210 * to display formatted html, so we use a simple alternative
212 String text = "<html><br><img src=\""
213 + ChannelProperties.getImageURL("banner") + "\"/>" + newtext
215 JLabel ta = new JLabel(text);
217 ta.setBackground(Color.white);
227 JTextPane jtp = new JTextPane();
228 jtp.setEditable(false);
229 jtp.setBackground(bg);
230 jtp.setForeground(fg);
232 jtp.setContentType("text/html");
233 jtp.setText("<html>" + newtext + "</html>");
234 jtp.addHyperlinkListener(this);
237 splashText.addMouseListener(closer);
239 splashText.setVisible(true);
240 splashText.setSize(new Dimension(750,
241 375 + logoSize + (Platform.isJS() ? 40 : 0)));
242 splashText.setBackground(bg);
243 splashText.setForeground(fg);
244 splashText.setFont(font);
245 add(splashText, BorderLayout.CENTER);
247 int width = Math.max(splashText.getWidth(), iconimg.getWidth());
248 int height = splashText.getHeight() + iconimg.getHeight();
249 iframe.setBounds((iframe.getParent().getWidth() - width) / 2,
250 (iframe.getParent().getHeight() - height) / 2,
253 iframe.setVisible(true);
257 protected void closeSplash()
262 iframe.setClosed(true);
263 } catch (Exception ex)
269 * A simple state machine with just three states: init, loop, and done. Ideal
270 * for a simple while/sleep loop that works in Java and JavaScript
275 public boolean stateLoop()
279 switch (helper.getState())
282 initSplashScreenWindow();
283 helper.setState(STATE_LOOP);
288 helper.setState(STATE_DONE);
296 helper.delayedState(SHOW_FOR_SECS * 1000, STATE_DONE);
302 Desktop.getInstance().startDialogQueue();
309 private class SplashImage extends JPanel
313 public SplashImage(Image todisplay)
318 setPreferredSize(new Dimension(image.getWidth(this) + 8,
319 image.getHeight(this)));
324 public Dimension getPreferredSize()
326 return new Dimension(image.getWidth(this) + 8, image.getHeight(this));
330 public void paintComponent(Graphics g)
333 g.fillRect(0, 0, getWidth(), getHeight());
335 g.setFont(new Font(font.getFontName(), Font.BOLD, FONT_SIZE + 6));
339 g.drawImage(image, (getWidth() - image.getWidth(this)) / 2,
340 (getHeight() - image.getHeight(this)) / 2, this);
346 public void hyperlinkUpdate(HyperlinkEvent e)
348 Desktop.hyperlinkUpdate(e);