Качать:Невозможно обновить JButton - repaint() не работает
-
13-09-2019 - |
Вопрос
Я впервые использую Swing для создания простого графического интерфейса.Он состоит из JFrame
на котором я разместил один JButton
который при нажатии вызывает какой-то другой код, который занимает ок.3 секунды, чтобы вернуться.
Непосредственно перед вызовом этого кода в actionPerformed()
, я хочу обновить текст на кнопке, чтобы информировать пользователя о том, что происходит обработка.Моя проблема в том, что текст на кнопке не обновляется до тех пор, пока не вернется 3-секундный вызов.Я хочу, чтобы обновленный текст присутствовал во время звонка, а потом я верну его обратно.
Вызов repaint()
на JButton
ничего не делает и вызывает его на JFrame
приводит к "Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
"выбрасывается, когда я нажимаю кнопку.
Решение
Происходит следующее: 3-секундный код выполняется в потоке графического интерфейса, поэтому у кнопки нет возможности обновиться, пока это не будет выполнено.
Чтобы решить эту проблему, запустите SwingWorker
выполнить длительную операцию;тогда вы все равно сможете делать что-то в графическом интерфейсе, пока ждете его.
Вот пара из обучающие программы по этому вопросу, и SwingWorker
В документации Java, упомянутой выше, также есть некоторый код.
Образец кода
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();
}
Другие советы
Проблема здесь в том, что ваша длительная задача блокирует поток, который обычно рисует графический интерфейс.
Обычный способ обойти эту проблему — перенести более длительную задачу в другой поток.
Это можно сделать довольно легко, используя SwingWorker
.
Этот вопрос также может предоставить некоторую полезную информацию.