GUI должен ждать, пока не закончится выполнение заставки

1

У меня есть класс SplashScreen, который отображает изображение и индикатор выполнения до тех пор, пока не будут инициализированы некоторые базы данных. Я хочу, чтобы после завершения всплывающего окна открылось новое окно. У меня есть следующий код:

Основной класс

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

}

Класс заставки экрана

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

}

Когда я запускаю код, я получаю одновременно и заставку, и окно изображения, я пытался использовать worker.get() но затем ничего не появляется на экране. Не могли бы вы дать мне совет? Я новичок в Java Swing.

Кстати, было бы возможно (с возможным значением не сумасшедшая загрузка кода и часов, чтобы заставить его работать), например, реализовать окно входа в систему, подобное этому?

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

Спасибо, совет.

Теги:
swing
concurrency
swingworker

1 ответ

2
Лучший ответ

Измените свой образ мышления

Инициализируйте и покажите заставку, когда закончите, инициализируйте и покажите 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();
    }

Затем вы слушаете свойство изменения 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();
            }
        }
    });
}

Но помните, вам нужно удалить заставку из кода Gui.

Вы также можете использовать это, чтобы "получить" любую информацию от SwingWorker которая может понадобиться Gui и передать ее как параметр конструктору или через сеттеры в зависимости от ваших потребностей

Кроме того, для меня это...

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

Похоже, странная вещь в SwingWoker. Вы можете просто оставить JProgressBar в неопределенном режиме, если вы не знаете, сколько требуется работы

  • 0
    Большое спасибо за ваш совет и ваш ответ!
  • 0
    Рад, что это могло помочь ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню