为 Java 桌面应用程序添加 Splash 屏幕

版权声明:转载时请务必保留以下作者信息和链接
作者:陈维([email protected])作者的网站:http://www.chenwei.mobi

当应用程序启动初始,进行各种类库的初始化和装载,此时出现一个醒目的 Splash 屏幕提示着用户软件正在进行初始化工作,同时可以通过显示广告、法律许可和软件 logo 等等,给予软件用户更积极的反馈。

熟悉 Java SE 6 的朋友应该知道 Java 6 允许一个应用程序在 JVM 启动前就可以显示一个 Splash 屏幕,而我今天要说的是针对无数使用旧版本 Java 的用户——如何在使用 Java 6 之前版本开发的软件中创建一个 Splash 屏幕。

我们可以把 Splash 屏幕看作一个在程序主窗体显示前显示的画布组件,当程序初始化完毕,主窗体在屏幕上显示后Splash 屏幕自动关闭,完成它的使命。

在了解了 Splash 屏幕的行为及作用后,我选择扩展 JDialog 来完成对它的实现。

首先定制 JDialog 的外观使它符合 Splash 屏幕的外形。

在构造函数通过设置设置属性 alwaysOnTop使窗体变成顶层窗体永远出现在屏幕最上层;属性 undecorated 禁用 dialog 的装饰,这样可以去除窗体上的文本栏以及窗体最大 / 最小化 / 关闭按钮,使其完全作为一个画布存在;最后根据将在其上绘制图像的大小尺寸设置 size属性并且将 locationRelativeTo 属性设置为 null,使其显示时出现在屏幕正中。

setAlwaysOnTop( true );
setUndecorated(
true );
setSize(
new Dimension(image.getWidth(),image.getHeight()));
setLocationRelativeTo(
null );

然后覆写 dialog 的 paint(Graphics g) 方法完成指定图像(广告、法律许可和 logo 等等)在画布上的绘制。

public void paint(Graphicsg) ... {
if(image!=null)...{
g.drawImage(image,
0,0,this);
}

}

接下来我们需要编写控制 Splash 行为的代码。

从用户体验上看,Splash 屏幕在程序主窗体打开前显示,在主窗体打开后关闭。那么它必定和主窗体的打开事件相关联,我们在 dialog 的构造函数里传入一个主窗体的引用,向其添加一个 ComponentListener, 当主窗体变为可见时销毁当前的 dialog 实例。

frame.addComponentListener( new ComponentAdapter() ... {

@Override
publicvoidcomponentShown(ComponentEvente)...{
JSplashScreen.
this.dispose();
}

}
);

到这里,一个 Splash 屏幕的主要代码就完成了。

通过给它添加一个鼠标监听器用来监听鼠标按下事件,使其也可以作为 About 窗体使用。当鼠标在画布上点击,窗体自动销毁。同时,我们在这个组件里定义两个静态常量用来标识它是作为 Splash 还是 About 使用。

// publicstaticfinalintSPLASH_MODE=0;
// publicstaticfinalintABOUT_MODE=1;


if (mode == SPLASH_MODE) ... {
frame.addComponentListener(
newComponentAdapter()...{

@Override
publicvoidcomponentShown(ComponentEvente)...{
JSplashScreen.
this.dispose();
}

}
);
}
else ... {
addMouseListener(
newMouseAdapter()...{

@Override
publicvoidmouseClicked(java.awt.event.MouseEventevt)...{
dispose();
}

}
);
}

下面是 Splash 屏幕组件JSplashScreen.java 的完整代码

/**/ /*
*JSplashScreen.java
*
*Createdon2007年11月20日,下午1:42
*/

package mobi.chenwei.wing.swing;

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;

/***/ /**
*Splash Screen
*根据不同的mode属性设置,也可以作为About窗体使用。
*
*
@authorChenWei
*@websitewww.chenwei.mobi
*@[email protected]
*/

public class JSplashScreen extends javax.swing.JDialog ... {

publicstaticfinalintSPLASH_MODE=0;
publicstaticfinalintABOUT_MODE=1;
privateFrameframe=null;
privateintmode=SPLASH_MODE;
privateBufferedImageimage=null;


publicJSplashScreen(Frameframe,intmode,BufferedImageimage)...{

if(frame==null)...{
thrownewIllegalArgumentException("framemustbenonnull");
}

if(mode!=SPLASH_MODE&&mode!=ABOUT_MODE)...{
thrownewIllegalArgumentException("modemustbeoneof:SPLASH_MODEorABOUT_MODE");
}

if(image==null)...{
thrownewIllegalArgumentException("imagemustbenonnull");
}


this.frame=frame;
this.mode=mode;
this.image=image;

if(mode==SPLASH_MODE)...{
frame.addComponentListener(
newComponentAdapter()...{

@Override
publicvoidcomponentShown(ComponentEvente)...{
JSplashScreen.
this.dispose();
}

}
);
}
else...{
addMouseListener(
newMouseAdapter()...{

@Override
publicvoidmouseClicked(java.awt.event.MouseEventevt)...{
JSplashScreen.this. dispose();
}

}
);
}


initComponents();

setSize(
newDimension(image.getWidth(),image.getHeight()));
setLocationRelativeTo(
null);
}


/***//**Thismethodiscalledfromwithintheconstructorto
*initializetheform.
*WARNING:DoNOTmodifythiscode.Thecontentofthismethodis
*alwaysregeneratedbytheFormEditor.
*/

//<editor-folddefaultstate="collapsed"desc="GeneratedCode">
privatevoidinitComponents()...{

setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setAlwaysOnTop(
true);
setUndecorated(
true);
getContentPane().setLayout(
null);
}
//</editor-fold>

@Override
publicvoidpaint(Graphicsg)...{
if(image!=null)...{
g.drawImage(image,
0,0,this);
}

}

}

使用方法:

package mobi.chenwei.wing.swing;

import java.awt.image.BufferedImage;

/***/ /**
*SplashScreen的测试类
*
*
@authorChenWei
*@websitewww.chenwei.mobi
*@[email protected]
*/

public class TestSplash extends javax.swing.JFrame ... {

publicTestSplash()...{

//给Splash屏幕添加一个背景图
BufferedImageimage=newBufferedImage(400,300,BufferedImage.TYPE_INT_BGR);
//初始化Splash屏幕并显示
JSplashScreensplash=newJSplashScreen(this,JSplashScreen.SPLASH_MODE,image);
splash.setVisible(
true);

//耗时的初始化方法
initComponents();

}


privatevoidinitComponents()...{

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

java.awt.DimensionscreenSize
=java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width
-800)/2,(screenSize.height-600)/2,800,600);

}


publicstaticvoidmain(Stringargs[])...{
java.awt.EventQueue.invokeLater(
newRunnable()...{

publicvoidrun()...{
newTestSplash().setVisible(true);
}

}
);
}


}

JSplashSceen 组件应用在 Panowalker_1.0 上的屏幕截图

为 Java 桌面应用程序添加 Splash 屏幕_第1张图片

你可能感兴趣的:(java,jvm,swing,软件测试)