Java GUI必须等待splashscreen完成执行

Java GUI必须等待splashscreen完成执行,java,swing,concurrency,swingworker,Java,Swing,Concurrency,Swingworker,我有一个SplashScreen类,它显示一个图像和一个进度条,直到一些数据库被初始化。我希望在splashscreen结束后打开一个新窗口。我有以下代码: 主类 } 启动屏幕类 公共类初始化屏幕{ 专用JDialog对话框; 私人酒吧进展; public void initUI()引发畸形的DurException{ showSplashScreen(); SwingWorker worker=新SwingWorker(){ @凌驾 受保护的Void doInBackground()引发异常{

我有一个SplashScreen类,它显示一个图像和一个进度条,直到一些数据库被初始化。我希望在splashscreen结束后打开一个新窗口。我有以下代码:

主类 }

启动屏幕类
公共类初始化屏幕{
专用JDialog对话框;
私人酒吧进展;
public void initUI()引发畸形的DurException{
showSplashScreen();
SwingWorker worker=新SwingWorker(){
@凌驾
受保护的Void doInBackground()引发异常{
线程线程=新线程(new InitProcess());
thread.start();
int i=0;
while(thread.isAlive()){
i++;
Thread.sleep(200);//加载数据库
发布(i);//通知进度
}
如果(i<10){
对于(i=0;i<100;i++){
sleep(50);//即使数据库已完全加载,我们也会模拟加载
发布(i);//通知进度
}
}
返回null;
}
@凌驾
受保护的无效进程(列表块){
setValue(chunks.get(chunks.size()-1));
}
@凌驾
受保护的void done(){
hideSplashScreen();
}
};
worker.execute();
}
受保护的void hideSplashScreen(){
对话框.setVisible(false);
dialog.dispose();
}
受保护的void showSplashScreen()引发畸形的DurException{
dialog=newjdialog((Frame)null);
dialog.setModal(false);
对话框。设置未装饰(true);
JLabel background=新的JLabel(新的图像图标(“splashscreendef.jpg”);
setLayout(新的BorderLayout());
对话框。添加(背景);
进度=新的JProgressBar();
背景。添加(进度,边界布局。南);
dialog.pack();
对话框.setLocationRelativeTo(空);
对话框.setVisible(true);
}
}
当我同时运行启动屏幕和图像窗口上的代码时,我尝试使用
worker.get()
,但屏幕上什么也没有显示。你能给我一些建议吗?我对Java Swing还很陌生

顺便问一下,例如,有没有可能实现这样一个登录窗口(可能意味着不需要花费大量的代码和时间才能使其正常工作)


谢谢你的建议。

改变你的思维方式

初始化并显示启动屏幕,完成后,初始化并显示
Gui

这需要有某种方法来告诉谁初始化过启动屏幕,启动屏幕已经完成。要做到这一点,您可以使用
PropertyChangeListener

public class InitSplashScreen {
    //...
    public void initUI(PropertyChangeListener listener) throws MalformedURLException {
        showSplashScreen();
        SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
            //...
        };
        worker.addPropertyChangeListener(listener);
        worker.execute();
    }
但是请记住,您需要从
Gui
代码中删除启动屏幕

您还可以使用它从
SwingWorker
获取
Gui
可能需要的任何信息,并根据您的需要将其作为参数传递给构造函数或通过setter

还有,对我来说,这

Thread thread = new Thread(new InitProcess());
thread.start();

SwingWoker
内执行看起来很奇怪。如果您不知道需要做多少工作,只需将
JProgressBar
置于模式即可

非常感谢您的建议和回答!
public class InitSplashScreen {
    //...
    public void initUI(PropertyChangeListener listener) throws MalformedURLException {
        showSplashScreen();
        SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
            //...
        };
        worker.addPropertyChangeListener(listener);
        worker.execute();
    }
public static void main(String[] args) throws ClassNotFoundException,
                InstantiationException, IllegalAccessException,
                UnsupportedLookAndFeelException {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            InitSplashScreen splashScreen = new InitSplashScreen();
            try {
                splashScreen.initUI(new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        String name = evt.getPropertyName();
                        if ("state".equalsIgnoreCase(name)) {
                            SwingWorker worker = (SwingWorker) evt.getSource();
                            if (worker.getState().equals(SwingWorker.StateValue.DONE)) {
                                Gui ui = new Gui();
                            }
                        }
                    }
                });
            } catch (MalformedURLException ex) {
                ex.printStackTrace();
            }
        }
    });
}
Thread thread = new Thread(new InitProcess());
thread.start();