javax.swing.JFrame setText () в цикле? + преднамеренная задержка? - PullRequest
3 голосов
/ 05 сентября 2011

Я очень новичок в Java (использую его только около недели) и работаю над симулятором магазина.По сути, я просто хочу сделать основные вещи прямо сейчас, такие как время до закрытия и время с момента открытия переменной, отображаемой на экране.

Я сделал следующие функции в моем расширении Simulation javax.swing.JFrame class:

public void incOpenTime() {
    timeOpen++;
    int hours = timeOpen / 3600;
    int minutes = (timeOpen % 3600) / 60;
    int seconds = (timeOpen % 3600) % 60;
    this.openTime.setText((hours < 10 ? "0" : "") + hours
            + ":" + (minutes < 10 ? "0" : "") + minutes
            + ":" + (seconds < 10 ? "0" : "") + seconds);
    decTimeLeft();
    }

public void decTimeLeft() {
    int remainingTime = 28800 - timeOpen;
    int hours = remainingTime / 3600;
    int minutes = (remainingTime % 3600) / 60;
    int seconds = (remainingTime % 3600) % 60;
    this.timeLeft.setText((hours < 10 ? "0" : "") + hours
            + ":" + (minutes < 10 ? "0" : "") + minutes
            + ":" + (seconds < 10 ? "0" : "") + seconds);

    }

Переменные openTime и timeLeft, использующие метод setText (), являются частью самого графического интерфейса.

В основном я называю incOpenTime следующим образом:

while(this.timeOpen < 28800) 
{
    incOpenTime();

}

Прежде всего, когда я запускаю это, он в основном просто проходит через цикл и выводит только последний раз на экран.Как бы я сделал так, чтобы время постоянно менялось?

Во-вторых, я хотел бы немного задержать его ... возможно, около 1 мс в секунду, чтобы моделирование работало медленнее, а другие данные выводились на экран (позже) более читабельно.Я пробовал Thread.sleep (1);в цикле, но он не отображает числа при их изменении.

Пожалуйста, помогите.

Спасибо

РЕДАКТИРОВАТЬ:

Вот что я сделалчтобы это заработало.В основном:

timer = new Timer();
for(int i=1; i<= 28800; i++)
{
        timer.schedule(new task(), 1*i);

}

Сделан новый класс:

class task extends TimerTask {

    @Override
    public void run() {
        incOpenTime();
        }
}

Ответы [ 3 ]

5 голосов
/ 05 сентября 2011

javax.swing.Timer может быть хорошим выбором, поскольку «обработчики событий действия для Timers выполняются в… потоке диспетчеризации событий».Вот пример здесь .

3 голосов
/ 05 сентября 2011

ваш вывод из задания BackGroung или потока в графический интерфейс неправильно отправлен в EDT,

Вы должны обернуть любой вывод в GUI (из BackGroung Task или Thread) в

invokeLater()

если метод может быть синхронизирован, то

invokeAndWait()

пожалуйста, прочитайте больше о Конкуренция в Swing

0 голосов
/ 05 сентября 2011

Вам нужно java.util.Timer

Edit: так как это принятый ответ, важно отметить, что TimerTask должен выполнить Runnable в потоке диспетчеризации событий. Правильный вариант этого подхода отмечен в ответе @ 1010 * mKorbel . Ниже приведен короткий пример и более сложный здесь . Несколько более простой подход, предложенный @Hovercraft, виден здесь .

class Task extends TimerTask {

    @Override
    public void run() {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                incOpenTime();
            }
        });
    }
}
...