Swing: не удается получить JButton для обновления-перекрасить() не работает

Я впервые использую Swing для создания простого GUI. Он состоит из JFrame на который я поместил один JButton который при нажатии вызывает другой код, который занимает ок. 3 секунды до возвращения.

просто перед вызовом этого кода, в actionPerformed(), Я хочу обновить текст на кнопке, чтобы сообщить пользователю, что происходит обработка. Моя проблема в том, что текст на кнопке не обновляется до тех пор, пока не вернется 3-секундный вызов. Я хочу обновленную текст, который будет присутствовать во время звонка, затем я изменю его обратно.

вызов repaint() на JButton ничего не делает и вызывает его на JFrame результаты в "Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException " бросается, когда я нажимаю кнопку.

2 ответов


происходит то, что 3-секундный код выполняется в потоке GUI, поэтому у кнопки нет возможности обновить, пока это не будет сделано.

чтобы решить эту проблему, начать SwingWorker для выполнения длительной операции; тогда вы все равно будете свободны делать что-то в GUI, пока вы его ждете.

здесь пара of уроки на эту тему, и SwingWorker Javadocs, упомянутые выше, имеют некоторый код также.

пример кода

public void actionPerformed(ActionEvent e) {
    SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
        @Override
        public Void doInBackground() {
            // Call complicated code here
            return null;
            // If you want to return something other than null, change
            // the generic type to something other than Void.
            // This method's return value will be available via get() once the
            // operation has completed.
        }

        @Override
        protected void done() {
            // get() would be available here if you want to use it
            myButton.setText("Done working");
        }
    };
    myButton.setText("Working...");
    worker.execute();
}

проблема здесь в том, что ваша длительная задача блокирует поток, который обычно рисует GUI.

обычный способ обойти это-выбросить более длинную задачу в другой поток.

Это можно сделать довольно легко, используя SwingWorker.

этот вопрос может предоставить некоторую полезную информацию.