Java: repaint() не работает?
Код:
@Override
public void mouseReleased(MouseEvent e) { //when the mouse is pressed
Point where=e.getPoint();
int x=(where.x-3)/20+1;
int y=(where.y-30)/20+1;
if(x>=1&&x<=30&&y>=1&&y<=30)
{
v[x][y]=1-v[x][y];
repaint();
try{
TimeUnit.MILLISECONDS.sleep(300);
}
catch(Exception ex){}
redo();
repaint();
}
}
Функция рисования сделана так, что она показывает на экране все элементы 30x30 V-матрицы. Функция повтора вносит некоторые изменения (детали не имеют значения) в V.
То, что я пытаюсь сделать, это нарисовать элементы V, но с измененным v[x][y] подождать 0,3 с, а затем снова закрасить элементы V, но на этот раз после того, как они были изменены функцией повтора. Но перекраска работает только второй раз, первый раз ничего не делает.
1 ответ
Спящий режим заблокирует поток, управляемый событиями (EDT) - постарайтесь не спать в основном потоке вашего приложения. EDT будет визуализировать ваши фреймы / диалоговые окна / панели, и будет реагировать на щелчки, меню и ввод с клавиатуры. В этой теме очень важно выполнять только быстрые задачи.
Как насчет добавления объекта Timer для запуска кода позже?
Timer timer = new Timer(300, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// runs code on the EDT to edit UI elements (recommended way)
redo();
repaint();
}
});
}
});
timer.setRepeats(false);
timer.start();
Таким образом, объект Timer создаст новый поток, задержит на 300 миллисекунд и затем вызовет метод actionPerformed. Это произойдет в потоке Таймера. Не рекомендуется изменять элементы пользовательского интерфейса из какого-либо потока, кроме EDT, поэтому мы используем метод invokeLater, который заставляет Swing запускать исполняемый файл на самом EDT - так что вернемся к исходному потоку.