Java 为什么它总是给出相同的时间?

Java 为什么它总是给出相同的时间?,java,swing,time,gregorian-calendar,Java,Swing,Time,Gregorian Calendar,我用下面的程序得到了时钟,结果是一个静态时钟?为什么会这样 import java.util.*; import java.awt.*; import javax.swing.*; class tester { JFrame fr = new JFrame(); JPanel p = new JPanel(); JLabel l = new JLabel(); Date d = new Date(); GregorianCalendar gc = ne

我用下面的程序得到了时钟,结果是一个静态时钟?为什么会这样

import java.util.*;
import java.awt.*;
import javax.swing.*;

class tester {

    JFrame fr = new JFrame();
    JPanel p = new JPanel();
    JLabel l = new JLabel();
    Date d = new Date();
    GregorianCalendar gc = new GregorianCalendar();

    tester() {
        p.setBackground(Color.red);
        l.setVisible(true);
        p.add(l);
        fr.add(p);
        fr.setSize(200,200);
        fr.setVisible(true);
        startClockThread();
    }

    public void startClockThread() {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                startClock();
            }
        };
        new Thread(r).start();
    }

    public void startClock() {
        l.setVisible(true);  
        while(true) {
            l.setText(gc.get(gc.HOUR) + ":" + gc.get(gc.MINUTE) + ":" + gc.get(gc.SECOND));
            System.out.println(gc.get(gc.SECOND));
        }
    }

    public static void main(String args[]) {
        new tester();
    } 
} 
GregorianCalendar()
使用默认时区中的当前时间和默认语言环境构建默认GregorianCalendar

你可以这样做

while(true) {
       GregorianCalendar gc = new GregorianCalendar();
   l.setText(gc.get(gc.HOUR) + ":" + gc.get(gc.MINUTE) + ":" + gc.get(gc.SECOND));
}
现在你应该明白为什么你会得到一个静态时钟

GregorianCalendar()
使用默认时区中的当前时间和默认语言环境构建默认GregorianCalendar

你可以这样做

while(true) {
       GregorianCalendar gc = new GregorianCalendar();
   l.setText(gc.get(gc.HOUR) + ":" + gc.get(gc.MINUTE) + ":" + gc.get(gc.SECOND));
}

现在你应该明白为什么你会得到一个静态时钟

您只创建了一次GregoriaCalendar,它永远不会更新。所以日期总是一样的。

您只创建了一次GregorianCalendar,它永远不会更新。所以日期总是一样的。

除了你发现的问题之外,还有一些大问题:

  • 不要让线程失控,它们最终会冻结ui
  • 每次访问Swing组件都必须在EDT上进行
通过使用javax.swing.Timer,可以最容易地解决这两个问题

ActionListener nextSecond = new ActionListener() {
     @Override
     public void actionPerformed(ActionEvent e) {
         // get time ...
         timeLabel.setText(...);
     }
}
new Timer(1000, nextSecond).start();

除了你所发现的问题之外,还有很多大问题:

  • 不要让线程失控,它们最终会冻结ui
  • 每次访问Swing组件都必须在EDT上进行
通过使用javax.swing.Timer,可以最容易地解决这两个问题

ActionListener nextSecond = new ActionListener() {
     @Override
     public void actionPerformed(ActionEvent e) {
         // get time ...
         timeLabel.setText(...);
     }
}
new Timer(1000, nextSecond).start();

我想知道这是否是在无限循环中构造多个对象的好方法?顺便说一句,有另一种解决方案,而不是每次构造一个新的GregorianCalendar实例:gc.setTimeInMillis(System.currentTimeInMillis());更好的是,不要连续循环1000毫秒。或者使用一个。这个方法有什么问题?@AlistairIsrael不,你从来没有在Swing程序中使用java.util.Timer,而是使用javax.Swing.Timer。我想知道这是否是在无限循环中构造多个对象的好方法?顺便说一句,有另一种解决方案,而不是每次构造一个新的GregorianCalendar实例:gc.setTimeInMillis(System.currentTimeInMillis());更好的是,不要连续循环1000毫秒。或者使用一个。这个方法有什么问题?@AlistairIsrael不,你从来没有在Swing程序中使用java.util.Timer-而是使用javax.Swing.Timer你应该编写一个Thread.sleep(1000);进入无限循环,除非你想让你的茶在处理器的顶部保持热度。请学习java命名约定并坚持它们。你应该写一个线程。sleep(1000);进入无限循环,除非你想让你的茶在处理器的顶部保持热度。请学习java命名约定,并坚持它们+1的优点。+1的优点。