[英]How to show a splash-screen, load datas in the background, and hide the splash-screen after that?
我正在设计一个简单的JavaFX表单。
首先,我加载JavaFX环境(并等待它完成),具体如下:
final CountDownLatch latch_l = new CountDownLatch(1);
try {
// init the JavaFX environment
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JFXPanel(); // init JavaFX
latch_l.countDown();
}
});
latch_l.await();
}
这很好用。 (之所以我需要首先以这种方式加载JavaFX,是因为它主要是一个Swing应用程序,里面有一些JavaFX组件,但是后来加载它们)
现在,我想在启动时添加一个启动画面,并在JavaFX环境加载时显示它(实际上在屏幕上放置了5秒钟,因为有应用程序的徽标,商标等...需要显示)
所以我想出了一个SplashScreen类,它只是在屏幕上显示一个JWindow,就像这样:
public class SplashScreen {
protected JWindow splashScreen_m = new JWindow();
protected Integer splashScreenDuration_m = 5000;
public void show() {
// fill the splash-screen with informations
...
// display the splash-screen
splashScreen_m.validate();
splashScreen_m.pack();
splashScreen_m.setLocationRelativeTo(null);
splashScreen_m.setVisible(true);
}
public void unload() {
// unload the splash-screen
splashScreen_m.setVisible(false);
splashScreen_m.dispose();
}
}
现在,我想让启动画面加载并显示5秒钟。 同时,我也希望加载JavaFX环境。
所以我更新了CountDownLatch,如下所示:
final CountDownLatch latch_l = new CountDownLatch(2); // now countdown is set to 2
final SplashScreen splash_l = new SplashScreen();
try {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// show splash-screen
splash_l.show();
latch_l.countDown();
// init the JavaFX environment
new JFXPanel(); // init JavaFX
latch_l.countDown();
}
});
latch_l.await();
splash_l.unload();
}
因此,它正在工作,但是只有JavaFX环境才能加载,因此基本上它会非常快速地卸载(这是正常的,考虑到我编写的代码)。
如何在不冻结EDT的情况下显示启动画面最少5秒(如果JavaFX加载速度更快)?
谢谢。
最重要的问题是您阻止了事件调度线程,这意味着它在被阻止时无法显示/更新任何内容。 同样的问题适用于JavaFX。
您也应该永远不会从其他任何事件队列中更新任何事件。
现在,您可以通过多种方式解决这个问题,但SwingWorker
可能是最简单的方式。
我道歉,这是我曾经有过的JavaFX的全部曝光......
public class TestJavaFXLoader extends JApplet {
public static void main(String[] args) {
new TestJavaFXLoader();
}
public TestJavaFXLoader() throws HeadlessException {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Loader loader = new Loader();
loader.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("state") && evt.getNewValue().equals(SwingWorker.StateValue.DONE)) {
System.out.println("Load main app here :D");
}
}
});
loader.load();
}
});
}
public class Loader extends SwingWorker<Object, String> {
private JWindow splash;
private JLabel subMessage;
public Loader() {
}
protected void loadSplashScreen() {
try {
splash = new JWindow();
JLabel content = new JLabel(new ImageIcon(ImageIO.read(...))));
content.setLayout(new GridBagLayout());
splash.setContentPane(content);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
subMessage = createLabel("");
splash.add(createLabel("Loading, please wait"), gbc);
splash.add(subMessage, gbc);
splash.pack();
splash.setLocationRelativeTo(null);
splash.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
protected JLabel createLabel(String msg) {
JLabel message = new JLabel("Loading, please wait");
message.setForeground(Color.CYAN);
Font font = message.getFont();
message.setFont(font.deriveFont(Font.BOLD, 24));
return message;
}
public void load() {
if (!EventQueue.isDispatchThread()) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
loadSplashScreen();
}
});
} catch (Exception exp) {
exp.printStackTrace();
}
} else {
loadSplashScreen();
}
execute();
}
@Override
protected void done() {
splash.dispose();
}
@Override
protected void process(List<String> chunks) {
subMessage.setText(chunks.get(chunks.size() - 1));
}
@Override
protected Object doInBackground() throws Exception {
publish("Preparing to load application");
try {
Thread.sleep(2500);
} catch (InterruptedException interruptedException) {
}
publish("Loading JavaFX...");
runAndWait(new Runnable() {
@Override
public void run() {
new JFXPanel();
}
});
try {
Thread.sleep(2500);
} catch (InterruptedException interruptedException) {
}
return null;
}
public void runAndWait(final Runnable run)
throws InterruptedException, ExecutionException {
if (Platform.isFxApplicationThread()) {
try {
run.run();
} catch (Exception e) {
throw new ExecutionException(e);
}
} else {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
lock.lock();
try {
Platform.runLater(new Runnable() {
@Override
public void run() {
lock.lock();
try {
run.run();
} catch (Throwable e) {
e.printStackTrace();
} finally {
try {
condition.signal();
} finally {
lock.unlock();
}
}
}
});
condition.await();
// if (throwableWrapper.t != null) {
// throw new ExecutionException(throwableWrapper.t);
// }
} finally {
lock.unlock();
}
}
}
}
}
我在这里找到了runAndWait
代码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.