Я пытаюсь написать простой графический интерфейс, который отображает некоторые цвета непрерывно в цикле. Цикл будет останавливаться при цвете, когда пользователь нажимает кнопку ввода, и возобновляет повторное нажатие.Java guis - прослушивание событий в бесконечном цикле
У меня, похоже, возникают проблемы. Когда я нажимаю один раз, он продолжает последний цвет в массиве, который является черным - когда он должен остановиться на цвет, который я нажал, введите. И когда я нажимаю войти еще раз, программа, кажется, просто повесить и пойти отвечать на запросы затем бросить ошибки как:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Timer already cancelled.
Могу ли я с помощью Timer
и TimerTask
неправильно?
Вот мой класс для этого:
import java.awt.Color;
import java.awt.Container;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
public class Rainbow extends JFrame {
public static final int PAUSED = 0;
public static final int PLAYING = 1;
private Timer timer;
private TimerTask task;
private int state;
private Color[] spectrum;
private Container c;
public static void main(String[] args) {
Rainbow r = new Rainbow();
}
public Rainbow() {
super("TASTE THE RAINBOW!");
createFrame();
setVisible(true);
timer = new Timer();
state = PLAYING;
task = new TimerTask() {
public void run() {
colorChange();
}
};
timer.schedule(task, Calendar.getInstance().getTime(), 1);
}
private void createFrame() {
c = getContentPane();
spectrum = new Color[] {Color.RED, Color.YELLOW, Color.GREEN, Color.BLUE, Color.BLACK};
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
c.setFocusable(true);
c.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER) {
if(state == PLAYING) {
System.out.println(1);
state = PAUSED;
timer.cancel();
} else {
System.out.println(2);
state = PLAYING;
timer.schedule(task, Calendar.getInstance().getTime(), 1);
}
}
}
});
}
private void colorChange() {
try {
while(state == PLAYING) {
for(int i = 0; i < spectrum.length; i++) {
c.setBackground(spectrum[i]);
Thread.sleep(1000);
}
}
} catch(Exception e) {
}
}
}
Update 2: Использование класса Timer. Добавлено поле private Timer timer;
Он initializied в конструкторе
timer = new Timer(5000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
colorChange();
}
});
timer.start();
И colorChange()
имеет время цикла удалены. Проблема: при запуске программы она остается на сером экране в течение 5 секунд, после чего она переходит на черный (последний цвет) и остается там. Графический интерфейс, похоже, не обновляется во время выполнения ActionPerformed?
Привет, спасибо за ваше предложение. Я читаю о классе Swing Timer. Я изменил свой код, чтобы использовать его, но, похоже, проблема. Когда я запускаю программу. он серый, а затем через 5 секунд он перескакивает до последнего цвета и остается черным – tenkii
@tenkii. The Thread.sleep() не позволяет графическому интерфейсу пересортировать себя, избавиться от него. Кроме того, таймер должен срабатывать каждую секунду. Затем вы меняете цвет фона. Когда индекс достигает 5, вы останавливаете таймер. См. Редактирование. – camickr
Я снял сон(), но он ничего не делает. Почему Таймеру нужно стрелять каждую секунду? Могу ли я не продолжать его стрелять каждые 5 секунд, поскольку это достаточно долго, чтобы каждый цвет отображался на экране один раз в секунду? – tenkii