对Java应用最常见的抱怨就是启动时间太长。这是因为Java虚拟机花费一段时间去加载所有必需的类,特别是对Swing应用,它们需要从Swing和AWT类库代码中去抽取大量的内容。

用户并不喜欢应用程序花费大量时间去产生初始屏幕,他们甚至可能不知道首次启动是否成功的情况下尝试着多次启动该应用程序。
此问题的解决之首是采用闪屏,即迅速出现的小窗体,它可以告诉用户该应用程序成功启动了。
传统上,这对于Java应用来说很难实现。当然,我们可以在main方法开始之后立即呈现一个窗体,但是,main方法只有在类加载器加载了所有需要依赖的类之后才会被启动,而这一过程可能要等上一段时间。

Java SE6支持虚拟机在启动时立即显示一幅图像而解决了这个问题。有两种机制可以指定这幅图像,一种使用命令行参数-splash:

java -splash:myImage.png package1.package2.MyApp

myImage.png文件需要在当前目录,否则要写全路径,相对或绝对
另一种是在JAR文件的清单中指定
Main-Class:package1.package2.MyApp
SplashScreen-Image:myimage.gif
这幅图像会在第一个AWT窗体可视时立即自动消失。我们可以使用任何GIF、JPEG或PNG图像,动画GIF和透明(GIF和PNG)都可以得到支持
如果应用程序在达到main之后即可立即执行,就不用考虑使用SplashScreen.

package swing.splash;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.SplashScreen;
import java.awt.Toolkit;
import java.util.List;
import java.util.concurrent.TimeUnit; import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker; /*2015-7-7*/
public class SplashScreenTest {
private static SplashScreen splash;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 300; public static void main(String[] args) throws InterruptedException {
init1();
SwingUtilities.invokeLater(new Runnable() { @Override
public void run() {
init2();
}
});
} protected static void init2() {
final Image img = Toolkit.getDefaultToolkit().getImage(splash.getImageURL());
final JFrame splashFrame = new JFrame();
splashFrame.setAlwaysOnTop(true);
splashFrame.setUndecorated(true);
final JPanel splashPanel = new JPanel() {
private static final long serialVersionUID = 1L; @Override
protected void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}; final JProgressBar progressBar = new JProgressBar();
progressBar.setStringPainted(true);
splashPanel.setLayout(new BorderLayout());
splashPanel.add(progressBar, BorderLayout.SOUTH); splashFrame.add(splashPanel);
splashFrame.setBounds(splash.getBounds());
splashFrame.setVisible(true); new SwingWorker<Void, Integer>() { @Override
protected Void doInBackground() throws Exception {
for (int i = 0; i < 100; i++) {
publish(i);
TimeUnit.SECONDS.sleep(1);
} return null;
} @Override
protected void process(List<Integer> chunks) {
for (Integer chunk : chunks) {
progressBar.setString("Loading module" + chunk);
progressBar.setValue(chunk);
System.out.println(chunk);
splashPanel.repaint();// because img is loaded asynchronously
}
} @Override
protected void done() {
splashFrame.setVisible(false);
JFrame frame = new JFrame();
frame.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("SplashScreenTest");
frame.setVisible(true);
frame.setLocationRelativeTo(null); } }; } private static void drawOnSplash(int percent) {
Rectangle bounds = splash.getBounds();
Graphics2D g = splash.createGraphics();
int height = 20;
int x = 2;
int y = bounds.height - height - 4;
int width = bounds.width - 4;
Color brightPurple = new Color(76, 36, 121);
g.setColor(brightPurple);
g.fillRect(x, y, width * percent / 100, height);
splash.update();
} private static void init1() throws InterruptedException {
splash = SplashScreen.getSplashScreen();
if (splash == null) {
System.err.println("Did you specify a splash image with -splash or in the manifest");
System.exit(1);
} for (int i = 0; i < 100; i++) {
drawOnSplash(i);
System.out.println("init1:"+i);
TimeUnit.SECONDS.sleep(1);
} } }

Tips:

SplashScreen是Singleton,因此不能创建自己的SplashScreen对象。如果在命令行或清单(MANIFEST.MF)中没有设置任何SplashScreen,getSplashScreen方法将返回null.

SplashScreenDemo的更多相关文章

随机推荐

  1. H264 编解码框架简单介绍

    阅读完H264/AVC 编解码器的介绍,脑海中仅仅是留下下面三条: 1.H264并没有明白规定一个编解码器怎样实现,仅仅是规定了一个编码后的视频比特流的句法,和该比特流的解码方法,这个与MPEG 类似 ...

  2. WPF弹性模拟动画

    原文:WPF弹性模拟动画 我们此次将要制作模拟物理中的弹性现象的交互动画,我们让一个小球向鼠标点击位置移动,这个移动的轨迹不是简单的位移,而是根据胡克定律计算得出的. 胡克定律:F=-kd F代表弹性 ...

  3. 一个css和js结合的下拉菜单,支持主流浏览器

    首先声明: 本人尽管在web前端岗位干了好多年,但无奈岗位对技术要求不高.html,css用的比較多,JavaScript自己原创的非常少,基本都是copy改动,所以自己真正动手写时,发现基础非常不坚 ...

  4. 移动web性能优化笔记

    移动web性能优化 最近看了一些文章,对移动web性能优化方法,做一个简单笔记 笔记内容主要出自 移动H5前端性能优化指南和移动前端系列——移动页面性能优化

  5. 黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Access Application Block

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Access Application Block 企业库数据库访问模块通过抽象工厂模式,允许用户 ...

  6. SVM-SVM概述

    (一)SVM背景资料简介 支持向量机(Support Vector Machine)这是Cortes和Vapnik至1995首次提出,样本.非线性及高维模式识别中表现出很多特有的优势,并可以推广应用到 ...

  7. android中的返回键与Activity

          我在做应用时遇到一个问题.就是在启动主页面时须要预先载入一些数据.我是在一个载入页中处理完这些数据然后再转到主页面.但当我在主页面中按返回键时,系统会返回载入页面.我不希望载入页在使用完之 ...

  8. 基于opencv在摄像头ubuntu根据视频获取

     基于opencv在摄像头ubuntu根据视频获取 1  工具 原料 平台 :UBUNTU12.04 安装库  Opencv-2.3 2  安装编译执行步骤 安装编译opencv-2.3  參考h ...

  9. 通过openssh远程登录时的延迟问题解决

    Linux下的ssh 服务器一般用的都是open-ssh,可是发现有些时候通过ssh连接服务器时总会有大概10秒钟左右的延迟. 一开始以为是openssh的安全策略,防止端口扫描,后来发现自己想多了. ...

  10. c++程序代写(qq:928900200)

     1. Both main memory and secondary storage are types of memory. Describe the difference between the  ...