我正在使用以下方式启动我的Scala SWT应用程序:
java -splash:splash.jpg -jar application.jar
在Mac OS X 10.9.1上使用JDK 1.6.0时,立即打开启动画面(实际应用程序窗口打开前几秒)。
我在打开SWT应用程序窗口时使用以下代码关闭启动画面:
// When the window opens for the first time close the splash screen if exists
val splash = SplashScreen.getSplashScreen
if (splash != null) {
shell.addShellListener(new ShellAdapter {
override def shellActivated(event: ShellEvent) {
shell.removeShellListener(this)
splash.close
}
})
}
行为符合预期: 当应用程序准备就绪时,我得到了一个非常早期的启动画面。
现在在JDK 1.7.0_45上,当应用程序窗口打开并且应用程序冻结在splash.close
时,启动屏幕就会打开。
我读到https://www.java.net//node/668622,对从Java 6到Java 7的SplashScreen
API进行了一些更改,但这并没有解释完全不同的行为。
在Java 7上为SWT应用程序运行JVM启动画面是否有变化?
仅供参考:我正在使用没有Eclipse的普通SWT(包括支持启动画面的Eclipse启动器)。
答案 0 :(得分:1)
也许在JDK9或更高版本中会有这样的解决方案。目前在OS X Yosemite上使用JDK8,这个问题没有任何改进。
目前,我将使用此代码段here或此there中的代码。他们两个都在工作。
希望这个bug将在JDK9中关闭!
答案 1 :(得分:0)
在运行时,您可以与Splash屏幕进行交互,而不会冻结应用程序中的其他线程。
我在Runnables中包含了对SplashScreen处理内容的所有调用(也是对其的渲染并将其解除)传递给此函数:
private static void executeSafeForMac( Runnable r ) {
// On non Mac systems no problem
if( System.getProperty("os.name").toLowerCase().indexOf("mac")<0 ) {
r.run();
return;
}
// On Mac we must be moar intelligent
Display display = Display.getDefault();
final Semaphore sem = new Semaphore(0);
Thread t = new Thread( ()->{
r.run();
sem.release(); // Can be anything.
display.asyncExec(()->{}); // Ensure the Event loop has one last thing to do
}, "SplashScreenInteractor" );
t.start();
// Okay, we do SWT event loop stuff to make the SplashScreen responsible until the
// SplashScreen stuff doing Runnable has been done and the semaphore is released.
while( !display.isDisposed() && !sem.tryAcquire() ) {
if( !display.readAndDispatch() ) {
display.sleep();
}
}
}