Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 14:43:25 GMT
  2. Package jalview.gui

File SplashScreen.java

 

Coverage histogram

../../img/srcFileCovDistChart8.png
20% of files have more coverage

Code metrics

28
111
12
2
371
260
33
0.3
9.25
6
2.75

Classes

Class Line # Actions
SplashScreen 56 101 28
0.776119477.6%
SplashScreen.SplashImage 329 10 5
0.8823529588.2%
 

Contributing tests

This file is covered by 2 tests. .

Source view

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.Component;
26    import java.awt.Dimension;
27    import java.awt.Font;
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;
33   
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.SwingUtilities;
40    import javax.swing.event.HyperlinkEvent;
41    import javax.swing.event.HyperlinkListener;
42   
43    import jalview.util.ChannelProperties;
44    import jalview.util.Platform;
45   
46    import javajs.async.SwingJSUtils.StateHelper;
47    import javajs.async.SwingJSUtils.StateMachine;
48   
49    /**
50    * DOCUMENT ME!
51    *
52    * @author $author$
53    * @version $Revision$
54    */
55    @SuppressWarnings("serial")
 
56    public class SplashScreen extends JPanel
57    implements HyperlinkListener, StateMachine
58    {
59   
60    private static final int STATE_INIT = 0;
61   
62    private static final int STATE_LOOP = 1;
63   
64    private static final int STATE_DONE = 2;
65    private static final int SHOW_FOR_SECS = 5;
66   
67    private static final int FONT_SIZE = (Platform.isJS() ? 14 : 11);
68   
69    private boolean visible = true;
70   
71    private JPanel iconimg = new JPanel(new BorderLayout());
72   
73    // could change fg, bg, font later to use ChannelProperties (these are not
74    // actually being used!)
75    private static Color bg = Color.WHITE;
76   
77    private static Color fg = Color.BLACK;
78   
79    private static Font font = new Font("SansSerif", Font.PLAIN, FONT_SIZE);
80   
81    private JPanel imgPanel = new JPanel(new BorderLayout());
82   
83    /*
84    * as JTextPane in Java, JLabel in javascript
85    */
86    private Component splashText;
87   
88    private JInternalFrame iframe;
89   
90    private Image image, logo;
91   
92    private boolean transientDialog = false;
93   
94    private long oldTextLength = -1;
95   
96    private StateHelper helper;
97    public static int logoSize = 32;
98   
99    /*
100    * allow click in the initial splash screen to dismiss it
101    * immediately (not if opened from About menu)
102    */
103    private MouseAdapter closer = new MouseAdapter()
104    {
 
105  0 toggle @Override
106    public void mousePressed(MouseEvent evt)
107    {
108  0 if (transientDialog)
109    {
110  0 try
111    {
112  0 closeSplash();
113    } catch (Exception ex)
114    {
115    }
116    }
117    }
118    };
119   
120    /**
121    * Constructor that displays the splash screen
122    *
123    * @param isStartup
124    * if true the panel removes itself on click or after a few seconds;
125    * if false it stays up until closed by the user (from Help..About menu)
126    */
 
127  11 toggle public SplashScreen(boolean isStartup)
128    {
129  11 this.transientDialog = isStartup;
130    // we must get the image in JavaScript BEFORE starting the helper,
131    // as it will take a 1 ms clock tick to obtain width and height information.
132   
133  11 image = ChannelProperties.getImage("banner");
134  11 logo = ChannelProperties.getImage("logo.48");
135  11 font = new Font("SansSerif", Font.PLAIN, FONT_SIZE);
136  11 helper = new StateHelper(this);
137  11 helper.next(STATE_INIT);
138    }
139   
 
140  11 toggle protected void initSplashScreenWindow()
141    {
142  11 addMouseListener(closer);
143  11 waitForImages();
144  11 setLayout(new BorderLayout());
145  11 iframe = new JInternalFrame();
146  11 iframe.setFrameIcon(null);
147  11 iframe.setClosable(true);
148  11 iframe.setContentPane(this);
149  11 iframe.setLayer(JLayeredPane.PALETTE_LAYER);
150  11 SplashImage splashimg = new SplashImage(image);
151  11 imgPanel.add(splashimg, BorderLayout.CENTER);
152  11 add(imgPanel, BorderLayout.NORTH);
153  11 Desktop.getDesktopPane().add(iframe);
154  11 refreshText();
155    }
156   
157    /**
158    * Both Java and JavaScript have to wait for images, but this method will
159    * accomplish nothing for JavaScript. We have already taken care of image
160    * loading with our state loop in JavaScript.
161    *
162    */
 
163  11 toggle private void waitForImages()
164    {
165  11 if (Platform.isJS())
166  0 return;
167  11 MediaTracker mt = new MediaTracker(this);
168  11 mt.addImage(image, 0);
169  11 mt.addImage(logo, 1);
170  11 do
171    {
172  11 try
173    {
174  11 mt.waitForAll();
175    } catch (InterruptedException x)
176    {
177    }
178  11 if (mt.isErrorAny())
179    {
180  0 jalview.bin.Console.errPrintln("Error when loading images!");
181  0 break;
182    }
183  11 } while (!mt.checkAll());
184  11 if (logo != null)
185    {
186  11 Desktop.getInstance().setIconImage(logo); // in 2.11.5.0 - this is ChannelProperties.getIconList());
187    }
188   
189  11 this.setBackground(bg);
190  11 this.setForeground(fg);
191  11 this.setFont(font);
192    }
193   
194    /**
195    * update text in author text panel reflecting current version information
196    */
 
197  22 toggle protected boolean refreshText()
198    {
199  22 String newtext = Desktop.getInstance().getAboutMessage();
200    // jalview.bin.Console.errPrintln("Text found: \n"+newtext+"\nEnd of
201    // newtext.");
202  22 if (oldTextLength == newtext.length())
203    {
204  11 return false;
205    }
206   
207  11 iframe.setVisible(false);
208  11 oldTextLength = newtext.length();
209  11 if (Platform.isJS()) // BH 2019
210    {
211    /*
212    * SwingJS doesn't have HTMLEditorKit, required for a JTextPane
213    * to display formatted html, so we use a simple alternative
214    */
215  0 String text = "<html><br><img src=\""
216    + ChannelProperties.getImageURL("banner") + "\"/>" + newtext
217    + "<br></html>";
218  0 JLabel ta = new JLabel(text);
219  0 ta.setOpaque(true);
220  0 ta.setBackground(Color.white);
221  0 splashText = ta;
222    }
223    else
224    /**
225    * Java only
226    *
227    * @j2sIgnore
228    */
229    {
230  11 JTextPane jtp = new JTextPane();
231  11 jtp.setEditable(false);
232  11 jtp.setBackground(bg);
233  11 jtp.setForeground(fg);
234  11 jtp.setFont(font);
235  11 jtp.setContentType("text/html");
236  11 jtp.setText("<html>" + newtext + "</html>");
237  11 jtp.addHyperlinkListener(this);
238  11 splashText = jtp;
239    }
240  11 splashText.addMouseListener(closer);
241   
242  11 splashText.setVisible(true);
243  11 splashText.setSize(new Dimension(750,
244  11 425 + logoSize + (Platform.isJS() ? 40 : 0)));
245  11 splashText.setBackground(bg);
246  11 splashText.setForeground(fg);
247  11 splashText.setFont(font);
248  11 add(splashText, BorderLayout.CENTER);
249  11 revalidate();
250  11 int width = Math.max(splashText.getWidth(), iconimg.getWidth());
251  11 int height = splashText.getHeight() + iconimg.getHeight();
252    // iframe.getParent() == Desktop.getInstance() unless running as embedded/plugin
253  11 iframe.setBounds((iframe.getParent().getWidth() - width) / 2,
254    (iframe.getParent().getHeight() - height) / 2,
255    width,height);
256  11 iframe.validate();
257  11 iframe.setVisible(true);
258  11 return true;
259    }
260   
 
261  5 toggle protected void closeSplash()
262    {
263  5 if (this.transientDialog)
264    {
265  5 Desktop.getInstance().releaseDialogQueue();
266    }
267  5 try
268    {
269  5 final JInternalFrame frme = iframe;
270  5 SwingUtilities.invokeLater(new Runnable()
271    {
 
272  5 toggle @Override
273    public void run()
274    {
275  5 try
276    {
277  5 frme.setClosed(true);
278    } catch (Exception ex)
279    {
280    }
281    }
282    });
283    } catch (Exception ex)
284    {
285    }
286    }
287   
288    /**
289    * A simple state machine with just three states: init, loop, and done. Ideal
290    * for a simple while/sleep loop that works in Java and JavaScript
291    * identically.
292    *
293    */
 
294  16 toggle @Override
295    public boolean stateLoop()
296    {
297  16 while (true)
298    {
299  27 switch (helper.getState())
300    {
301  11 case STATE_INIT:
302  11 initSplashScreenWindow();
303  11 helper.setState(STATE_LOOP);
304  11 continue;
305  11 case STATE_LOOP:
306  11 if (!isVisible())
307    {
308  0 helper.setState(STATE_DONE);
309  0 continue;
310    }
311  11 if (refreshText())
312    {
313  0 iframe.repaint();
314    }
315  11 if (transientDialog)
316  11 helper.delayedState(SHOW_FOR_SECS * 1000, STATE_DONE);
317  11 return true;
318  0 default:
319  5 case STATE_DONE:
320  5 setVisible(false);
321  5 closeSplash();
322  5 Desktop.getInstance().startDialogQueue();
323  5 return true;
324    }
325    }
326   
327    }
328   
 
329    private class SplashImage extends JPanel
330    {
331    Image image;
332   
 
333  11 toggle public SplashImage(Image todisplay)
334    {
335  11 image = todisplay;
336  11 if (image != null)
337    {
338  11 setPreferredSize(new Dimension(image.getWidth(this) + 8,
339    image.getHeight(this)));
340    }
341    }
342   
 
343  14 toggle @Override
344    public Dimension getPreferredSize()
345    {
346  14 return new Dimension(image.getWidth(this) + 8, image.getHeight(this));
347    }
348   
 
349  31 toggle @Override
350    public void paintComponent(Graphics g)
351    {
352  31 g.setColor(bg);
353  31 g.fillRect(0, 0, getWidth(), getHeight());
354  31 g.setColor(fg);
355  31 g.setFont(new Font(font.getFontName(), Font.BOLD, FONT_SIZE + 6));
356   
357  31 if (image != null)
358    {
359  31 g.drawImage(image, (getWidth() - image.getWidth(this)) / 2,
360    (getHeight() - image.getHeight(this)) / 2, this);
361    }
362    }
363    }
364   
 
365  0 toggle @Override
366    public void hyperlinkUpdate(HyperlinkEvent e)
367    {
368  0 Desktop.hyperlinkUpdate(e);
369   
370    }
371    }