简体   繁体   English

GUI必须等到启动屏幕完成执行

[英]GUI has to wait until splashscreen finishes executing

I have a SplashScreen class which displays a image and a progress bar until some databases are initialized. 我有一个SplashScreen类,它显示图像和进度条,直到初始化某些数据库为止。 I want that after the splashscreen ends a new window is opened. 我希望启动画面结束后打开一个新窗口。 I have the following code: 我有以下代码:

Main class 主班

public class Gui{

private static final String IMG_PATH = "../opt/images/splashscreendef.jpg";

public static void main(String[] args) throws ClassNotFoundException,
        InstantiationException, IllegalAccessException,
        UnsupportedLookAndFeelException {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Gui ui = new Gui();
        }
    });
}

private inTouchGui() {
    InitSplashScreen splash = null;
    splash = new InitSplashScreen();
    try {
        splash.initUI();
    } catch (MalformedURLException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    BufferedImage img = null;
    try {
        img = ImageIO.read(new File(IMG_PATH));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    ImageIcon icon = new ImageIcon(img);
    JLabel label = new JLabel(icon);
    JOptionPane.showMessageDialog(null, label);
}

} }

Splash screen class 开机画面类

public class InitSplashScreen {
private JDialog dialog;
private JProgressBar progress;

public void initUI() throws MalformedURLException {
    showSplashScreen();
    SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>(){

        @Override
        protected Void doInBackground() throws Exception {
            Thread thread = new Thread(new InitProcess());
            thread.start();
            int i = 0;
            while (thread.isAlive()){
                i++;
                Thread.sleep(200);// Loading of databases
                publish(i);// Notify progress
            }
            if (i < 10){
                for (i = 0; i < 100; i++){
                    Thread.sleep(50);// We simulate loading even if database is fully loaded
                    publish(i);// Notify progress
                }
            }
            return null;
        }

        @Override
        protected void process(List<Integer> chunks) {
            progress.setValue(chunks.get(chunks.size() - 1));
        }

        @Override
        protected void done() {
            hideSplashScreen();
        }

    };
    worker.execute();
}



protected void hideSplashScreen() {
    dialog.setVisible(false);
    dialog.dispose();
}

protected void showSplashScreen() throws MalformedURLException {
    dialog = new JDialog((Frame) null);
    dialog.setModal(false);
    dialog.setUndecorated(true);
    JLabel background = new JLabel(new ImageIcon("splashscreendef.jpg"));
    background.setLayout(new BorderLayout());
    dialog.add(background);
    progress = new JProgressBar();
    background.add(progress, BorderLayout.SOUTH);
    dialog.pack();
    dialog.setLocationRelativeTo(null);
    dialog.setVisible(true);
}

}

When I run the code I get at the same time both the splash screen and the image window, I have tried to use worker.get() but then nothing appears in screen. 当我运行代码时,同时显示初始屏幕和图像窗口,我尝试使用worker.get()但是屏幕上什么也没有出现。 Could you give me some advice? 你能给我一些建议吗? I am pretty new to Java Swing. 我对Java Swing很陌生。

By the way, would it be possible (with possible meaning not a insane load of code and hours to make it work) to implement a login window like this one, for example? 顺便说一句,是否有可能(例如,可能不会耗费大量代码和大量时间才能使其正常工作)来实现这样的登录窗口?

http://designsparkle.com/wp-content/uploads/2014/06/a-simple-html-css-login-for.jpg http://designsparkle.com/wp-content/uploads/2014/06/a-simple-html-css-login-for.jpg

Thanks in advice. 感谢您的建议。

Change your way of thinking 改变思维方式

Initialise and show the splash screen, when it's finished, initialise and show the Gui 初始化并显示启动屏幕,完成后初始化并显示Gui

This will require to have some way to tell who ever initialised the splash screen that it has completed, to do this, you can use a PropertyChangeListener ... 这将需要某种方法来告诉谁初始化了初始屏幕,即完成了该操作,您可以使用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();
    }

Then you listen for the state change property and check the state of the work... 然后,您侦听state更改属性并检查工作状态。

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();
            }
        }
    });
}

But remember, you need to remove the splash screen from the Gui code. 但是请记住,您需要从Gui代码中删除初始屏幕。

You can also use this to "get" any information from the SwingWorker that the Gui might need and pass it as a parameter to the constructor or via setters depending on your needs 您还可以使用它从SwingWorker中“获取” Gui可能需要的任何信息,并将其作为参数传递给构造函数或通过setter传递,具体取决于您的需求。

Also, to me, this... 另外,对我来说

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

Looks like a strange thing to do within a SwingWoker . SwingWoker看起来很奇怪。 You could simply leave the JProgressBar in indeterminate mode if you don't know how much work is required 如果您不知道需要多少工作,则可以简单地将JProgressBar保留为不确定模式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM