SplashScreenDemo

简介: 对Java应用最常见的抱怨就是启动时间太长。这是因为Java虚拟机花费一段时间去加载所有必需的类,特别是对Swing应用,它们需要从Swing和AWT类库代码中去抽取大量的内容。 用户并不喜欢应用程序花费大量时间去产生初始屏幕,他们甚至可能不知道首次启动是否成功的情况下尝试着多次启动该应用程序。

对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.


 

 

相关文章
|
6月前
|
前端开发 JavaScript API
前端 JS 经典:Proxy 和 DefineProperty
前端 JS 经典:Proxy 和 DefineProperty
90 0
|
5月前
|
存储 前端开发 对象存储
基于jsDelivr+Github给网站如何换个漂亮的字体。
本文介绍了如何为博客自定义字体。首先,从免费字体网站(如100字体下载站)下载字体,然后使用在线工具(如fontformat.com)转换字体格式为eot, woff, woff2, svg和ttf。接着,将字体文件上传至GitHub仓库,利用jsDelivr+GitHub的CDN服务获取文件链接。最后,通过编写@font-face的CSS样式代码,将自定义字体应用到博客中。注意文件名避免使用中文,并确保所有浏览器兼容。
55 2
|
6月前
|
Java 编译器
Java并发编程中的锁优化策略
【4月更文挑战第13天】 在Java并发编程中,锁是一种常见的同步机制,用于保证多个线程之间的数据一致性。然而,不当的锁使用可能导致性能下降,甚至死锁。本文将探讨Java并发编程中的锁优化策略,包括锁粗化、锁消除、锁降级等方法,以提高程序的执行效率。
42 4
|
前端开发 API
ElementUI之CUD+表单验证
ElementUI之CUD+表单验证
43 1
|
机器学习/深度学习 设计模式 自然语言处理
语言模型的冰山一角:微调是不必要, AI21 Labs探索冻结模型未开发潜力
语言模型的冰山一角:微调是不必要, AI21 Labs探索冻结模型未开发潜力
100 0
|
存储 自然语言处理 BI
软件需求分析
软件需求分析
205 0
|
JavaScript
002---项目的其他配置
002---项目的其他配置
118 0
|
搜索推荐 大数据 数据库
大数据获客,实时截流,真的有效果吗?
其实手机号抓取系统是根据数据库查询来记录运营商的流量消耗的。用户只要访问某个有流量的网站,就会有流量消耗的痕迹,运营商的系统软件里都有记录。最终达到大数据获客的效果。
大数据获客,实时截流,真的有效果吗?
|
SQL 并行计算 Oracle
【笔记】最佳实践—混合负载HTAP的实践和优化
背景信息 本文主要提供数据库上云后OLTP+OLAP一体化架构的最佳实践,既HTAP。主要面对的业务应用范围: 混合型HTAP数据库需求:如ORACLE数据库改造上云,云上数据库方案选型; OLTP系统查询慢,存在分析型场景和瓶颈的客户; 读写分离需求。
【笔记】最佳实践—混合负载HTAP的实践和优化
todolist正在进行个数和已完成个数-70
todolist正在进行个数和已完成个数-70
111 0
todolist正在进行个数和已完成个数-70