Качели не реагируют сразу! Как я могу это изменить? - PullRequest
3 голосов
/ 07 января 2009

Я создал форму с помощью визуального редактора Netbeans. Когда я нажимаю одну из кнопок, она должна сделать следующее:

  • отключить
  • выполнить задачу, которая занимает некоторое время
  • когда задание завершится, кнопка снова будет активирована

Однако происходит следующее:

  • кнопка остается в нажатом состоянии до завершения задачи
  • после завершения задачи включение / отключение кнопок будет очень быстрым (они произойдут, но вы их не заметите)

Такое поведение не то, чего я хочу. Я попытался использовать repaint на JButton, на JFrame и даже на JPanel, содержащей кнопку, но я не могу заставить ее делать то, что я хочу. Некоторые намеки?

Ответы [ 4 ]

13 голосов
/ 07 января 2009

Когда вы работаете с обратным вызовом кнопки, вы останавливаете поток рисования GUI до тех пор, пока он не завершится.

То, что вам нужно сделать, это создать поток для выполнения задачи, которая выполняется долго, а затем заставить этот поток использовать SwingUtilities.invokeLater() для обновления пользовательского интерфейса после его завершения. Неиспользование invokeLater не является потокобезопасным, и, как правило, плохо для mojo.

Базовый пример:

button.setEnabled(false);
new Thread(new Runnable() {
 public void run() {
  // Do heavy lifting here
  SwingUtilies.invokeLater(new Runnable() {
   public void run() {
    button.setEnabled(true);
   }
  });
 }
}).start();
8 голосов
/ 07 января 2009

Когда вы делаете что-то в функции обратного вызова кнопки, вы по сути останавливаете поток рисования графического интерфейса - не только для кнопки, но и для ЛЮБОГО рисования графического интерфейса. (Попробуйте закрыть интерфейс другим окном, а затем снова открыть его - он не будет перекрашиваться, пока задача не будет завершена!)

Что вам нужно сделать, это создать поток, чтобы выполнить долгосрочную задачу, а затем заставить этот поток использовать SwingUtilities.invokeLater (), чтобы включить кнопку. invokeLater вызывает включение кнопки в потоке рисования графического интерфейса.

Возможно, вы захотите установить занятый курсор или иным образом заблокировать интерфейс во время работы длинного потока.

4 голосов
/ 07 января 2009

Учебное пособие по по Swing от Sun стоит прочитать. Отличное объяснение и фоновое чтение, включая поток диспетчеризации событий, использование рабочих потоков и т. Д.

2 голосов
/ 07 января 2009

Вам нужно выполнить задачу, которая занимает некоторое время в другом потоке.

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

Если вы используете другой поток, поток будет выполнять задание, в то время как код рисования может продолжать рисовать форму.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...