/* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Toolkit; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.net.URL; import javax.swing.JInternalFrame; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.JTextPane; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import jalview.util.Platform; import javajs.async.SwingJSUtils.StateHelper; import javajs.async.SwingJSUtils.StateMachine; /** * DOCUMENT ME! * * @author $author$ * @version $Revision$ */ @SuppressWarnings("serial") public class SplashScreen extends JPanel implements HyperlinkListener, StateMachine { private static final int STATE_INIT = 0; private static final int STATE_LOOP = 1; private static final int STATE_DONE = 2; private static final int SHOW_FOR_SECS = 5; private int FONT_SIZE = (Platform.isJS() ? 14 : 11); private JPanel imgPanel = new JPanel(new BorderLayout()); private JInternalFrame iframe; private Image image, logo; 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) */ private MouseAdapter closer = new MouseAdapter() { @Override public void mousePressed(MouseEvent evt) { if (isStartup) { try { closeSplash(); } catch (Exception ex) { } } } }; /** * Constructor that displays the splash screen * * @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 (from Help..About menu) */ public SplashScreen(boolean isStartup) { 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); } protected void initSplashScreenWindow() { 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(); } /** * 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. * */ private void waitForImages() { if (Platform.isJS()) return; MediaTracker mt = new MediaTracker(this); try { mt.addImage(image, 0); logo = Toolkit.getDefaultToolkit().createImage( getClass().getResource("/images/Jalview_Logo_small.png")); } catch (Exception ex) { } if (logo != null) { mt.addImage(logo, 1); } do { try { mt.waitForAll(); } catch (InterruptedException x) { } if (mt.isErrorAny()) { System.err.println("Error when loading images!"); break; } } while (!mt.checkAll()); if (logo != null) { Desktop.getInstance().setIconImage(logo); } } /** * update text in author text panel reflecting current version information */ protected boolean refreshText() { String newtext = Desktop.getInstance().getAboutMessage(); if (oldTextLength == newtext.length()) { return false; } oldTextLength = newtext.length(); iframe.setVisible(false); JTextPane jtp = new JTextPane(); jtp.setEditable(false); jtp.setContentType("text/html"); jtp.setText("" + newtext + ""); jtp.addHyperlinkListener(this); jtp.setFont(new Font("Verdana", Font.PLAIN, FONT_SIZE)); jtp.addMouseListener(closer); jtp.setVisible(true); jtp.setSize(new Dimension(750, 425)); add(jtp, BorderLayout.CENTER); revalidate(); 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 void closeSplash() { try { iframe.setClosed(true); } catch (Exception ex) { } } /** * A simple state machine with just three states: init, loop, and done. Ideal * for a simple while/sleep loop that works in Java and JavaScript * identically. * */ @Override public boolean stateLoop() { while (true) { switch (helper.getState()) { case STATE_INIT: initSplashScreenWindow(); helper.setState(STATE_LOOP); continue; case STATE_LOOP: if (!isVisible()) { helper.setState(STATE_DONE); continue; } if (refreshText()) { iframe.repaint(); } if (isStartup) helper.delayedState(SHOW_FOR_SECS * 1000, STATE_DONE); return true; default: case STATE_DONE: setVisible(false); closeSplash(); Desktop.getInstance().startDialogQueue(); return true; } } } private class SplashImage extends JPanel { Image image; public SplashImage(Image todisplay) { image = todisplay; if (image != null) { setPreferredSize(new Dimension(image.getWidth(this) + 8, image.getHeight(this))); } } @Override public Dimension getPreferredSize() { return new Dimension(image.getWidth(this) + 8, image.getHeight(this)); } @Override public void paintComponent(Graphics g) { g.setColor(Color.white); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(Color.black); if (image != null) { g.drawImage(image, (getWidth() - image.getWidth(this)) / 2, (getHeight() - image.getHeight(this)) / 2, this); } } } @Override public void hyperlinkUpdate(HyperlinkEvent e) { Desktop.hyperlinkUpdate(e); } }