循环中的javax.swing.JFrame setText()? +故意拖延?

时间:2011-09-04 21:52:46

标签: java swing timer jframe event-dispatch-thread

我是Java的新手(仅使用它大约一周),我正在开发商店模拟器。基本上我只是希望现在能够完成基本的事情,比如有一段时间直到关闭以及屏幕上显示开启变量的时间。

我在我的Simulation扩展javax.swing.JFrame类中创建了以下函数:

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);

    }

使用setText()方法的openTime和timeLeft变量是GUI本身的一部分。

在main中,我这样称为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 个答案:

答案 0 :(得分:5)

javax.swing.Timer可能是一个不错的选择,因为“Timers的动作事件处理程序在...事件派发线程上执行。”有一个例子here

答案 1 :(得分:3)

从BackGroung任务或线程到GUI的输出未正确发布到EDT,

你必须将任何输出包装到GUI(从BackGroung任务或线程)到

invokeLater()

如果方法可以同步,那么

invokeAndWait()

请详细了解Concurency in Swing

答案 2 :(得分:0)

您需要java.util.Timer

编辑:由于这是已接受的答案,因此请务必注意TimerTask应在事件派发线程上执行其Runnable。 @ mKorbel approach中注明了此answer的正确变体。下面有一个简短的例子,还有一个更精细的例子here。 @Hovercraft建议的一种稍微简单的方法是here

class Task extends TimerTask {

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

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