Java 如何在JLabel上设置计时器以每秒更新自身

Java 如何在JLabel上设置计时器以每秒更新自身,java,swing,user-interface,timer,Java,Swing,User Interface,Timer,我创建了一个游戏,在我的swing GUI界面中我想放置一个计时器。目前我这样做的方式是,有一个带有当前时间的字段,由System.currentTimeMillis()获得,它在游戏开始时获取它的值;它告诉你从游戏开始到现在的时间 然而,如何让它每秒钟更新一次,比如说,JLabel将有:timePassed:0s、timePassed:1s等等。请记住,我在任何时候都不会在游戏中使用线程 编辑:谢谢大家的建议。我使用了你的答案组合,请给我一些反馈 我将JLabel作为一个名为time的字段。(

我创建了一个游戏,在我的swing GUI界面中我想放置一个计时器。目前我这样做的方式是,有一个带有当前时间的字段,由
System.currentTimeMillis()
获得,它在游戏开始时获取它的值;它告诉你从游戏开始到现在的时间

然而,如何让它每秒钟更新一次,比如说,
JLabel
将有:timePassed:0s、timePassed:1s等等。请记住,我在任何时候都不会在游戏中使用线程

编辑:谢谢大家的建议。我使用了你的答案组合,请给我一些反馈

我将JLabel作为一个名为time的字段。(要不然我受不了)


看一看这张照片。它允许非常轻松地设置重复任务。

在构造函数中编写此命令

new Thread(new Runnable
{
    public void run()
    {
        long start = System.currentTimeMillis();
        while (true)
        {
            long time = System.currentTimeMillis() - start;
            int seconds = time / 1000;
            SwingUtilities.invokeLater(new Runnable() {
                 public void run()
                 {
                       label.setText("Time Passed: " + seconds);
                 }
            });
            try { Thread.sleep(100); } catch(Exception e) {}
        }
    }
}).start();
ActionListener taskPerformer=新建ActionListener(){

这个写出构造函数

公共字符串CurrentTime(){

Calendar cal=new gregoriacalendar();
int second=cal.get(Calendar.second);
int min=cal.get(日历分钟);
int hour=cal.get(日历小时);
字符串s=(检查时间(小时)+“:”+检查时间(分钟)+“:”+检查时间(秒));
jMenu11.setText(s);
返回s;
}
公共字符串检查时间(int t){
字符串时间1;
if(t<10){
时间1=(“0”+t);
}
否则{
时间1=(“”+t);
}
返回时间1;

}

这是我设置JLabel以随时间和日期更新的方式

Timer SimpleTimer = new Timer(1000, new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        jLabel1.setText(SimpleDay.format(new Date()));
        jLabel2.setText(SimpleDate.format(new Date()));
        jLabel3.setText(SimpleTime.format(new Date()));
    }
});
SimpleTimer.start();

然后,这将添加到主类中,jlabel1/2/3将使用计时器进行更新。

答案在问题中。看看如果使用Swing,那么您确实使用线程。您不可能只在EDT中完成所有操作!错误..是的,我可以:p我的gui用于从一个显示导航到另一个显示,即从主菜单到播放屏幕再到选项screen等。尽管2个或3个窗口可以在任何给定时间保持打开状态,但我永远不会使用重复的窗口。那么,问题是什么?您更新的代码看起来不错。是的,JLabel需要保存在一个变量中才能工作,可以是一个最终的局部变量,也可以是一个非静态类字段。我唯一的批评是,应该努力避免使用“幻数”,这里是1000。为此使用一个常量,以便将来需要时可以更轻松地更改它。永远不要访问Swing组件(
label.setText(…)
)在EDT之外!@jfpoilpret:还有什么选择?如何使它工作而不使用标签更新程序循环锁定EDT。@Martinos:按照Howard的Swing timer建议进行。虽然Marijn的意思是好的,但他的答案不被推荐。@Martijn:Swing timer负责循环(它在幕后使用后台线程),并具有在EDT上调用actionPerformed块中的所有代码的优点。如果必须直接使用后台线程,则可以方便地使用SwingWorker来帮助确保在EDT上调用Swing代码。如果无法使用SwingWorker,则必须注意通过
SwingUtilities.invokeLa将EDT上的所有Swing代码排队ter(myRunnable);
@Martijn,代码不好:没有循环的出口。无论如何,至少测试:
如果(!label.isDisplayable())
。@gcclinux你说的SimpleDay,SimpleTime是什么意思?!,它们是变量还是类?
             @Override

            public void actionPerformed(ActionEvent evt) {
               jMenu11.setText(CurrentTime());
            }
        };

        Timer t = new Timer(1000, taskPerformer);
        t.start();
       Calendar cal = new GregorianCalendar();
       int second = cal.get(Calendar.SECOND);
       int min = cal.get(Calendar.MINUTE);
       int hour = cal.get(Calendar.HOUR);
       String s=(checkTime(hour)+":"+checkTime(min)+":"+checkTime(second));
       jMenu11.setText(s);
       return s;

   }

   public String checkTime(int t){
String time1;
if (t < 10){
    time1 = ("0"+t);
    }
else{
    time1 = (""+t);
    }
return time1;
Timer SimpleTimer = new Timer(1000, new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        jLabel1.setText(SimpleDay.format(new Date()));
        jLabel2.setText(SimpleDate.format(new Date()));
        jLabel3.setText(SimpleTime.format(new Date()));
    }
});
SimpleTimer.start();