Есть два варианта:
- Начать новую тему. Поток будет содержать цикл while и выполнит метод, который обрабатывает массив. На каждой итерации вызывайте
repaint()
или invalidate()
в своем окне, чтобы сообщить, что оно нуждается в перерисовке.
- Используйте таймер. Поток GUI будет вызывать вашу процедуру через регулярные промежутки времени.
Тема:
В методе actionPerformed
создайте новый поток. и вызвать его метод запуска.
Runnable
потока должен запустить цикл while (как вы уже сделали), а затем просто выйти.
Таймер:
Создайте объект в вашем классе типа Timer. Используйте тот из java.swing.Timer
, если вы используете Swing (есть также java.util.Timer
, который не подходит для операций с графическим интерфейсом). Таймер должен иметь ActionListener
, который вызывает ваш метод один раз, но таймер имеет частоту повторения 1000 мс.
Советы
- чтобы вызвать действие, вы должны поместить его в отдельный метод, а не прямо под обработчик кнопки. Таким образом, вы не вызываете вещи из GUI вне потока GUI.
, например
tickButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
doTick();
}
});
Не менее важен механизм остановки нити! В общем, не используйте while(true)
в потоке, так как он будет потерян; придумайте семафор, чтобы прекратить его.
используйте JToggleButton
вместо Button
?
Синхронизация:
Если вы используете потоки, вам понадобится что-то вроде этого, чтобы новые потоки не создавались при каждом нажатии кнопки:
Код
Thread autoplayThread = null;
Object lock;
boolean autoplaying = false;
public void actionPerformed(ActionEvent e){
synchronized(lock){ // prevent any race condition here
if(!autoplaying && autoplayThread==null ){
autoplaying = true;
autoplayThread = new Thread(new Runnable(){
public void run(){
try{
while(autoplaying){ .... }
}finally{
synchronized(lock) {
autoplaying=false;
autoplayThread=null;
}
}
}
});
autoplayThread.start();
}else{ // stop the thread!
autoplaying=false;
}
}
}