【问题标题】:Java - How to update a panel every secondJava - 如何每秒更新一个面板
【发布时间】:2013-11-01 13:12:25
【问题描述】:

我正在尝试创建一个显示当前时间的 Java GUI。目前,我可以让它显示当前时间,但只能在启动时显示。然后它就永远停留在那个时间。原因是我无法弄清楚如何让它每秒自动加载到新的当前时间。到目前为止,这是我的相关代码:

// Getting the current time...
long epoch = System.currentTimeMillis() / 1000;
String date = new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date(epoch * 1000));

// Creating the panel...
JLabel lblThetime = new JLabel(date);
sl_panel.putConstraint(SpringLayout.NORTH, lblThetime, 55, SpringLayout.SOUTH, lblIBeA);
sl_panel.putConstraint(SpringLayout.WEST, lblThetime, 139, SpringLayout.WEST, panel);
lblThetime.setFont(new Font("Avenir Next", Font.PLAIN, 40));
    
// Adding the time to the panel
panel.add(lblThetime);
    
// My refresher which doesn't work
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        removeAll();
        validate();
        repaint();
    }
}, 1000, 1000);

我尝试使用来自this thread 的信息进行复习,但无济于事,窗口(运行时)只是空白。然后我尝试使用来自this thread 的信息进行不同的复习,并创建了这个:

// My refresher which doesn't work
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        contentPane.remove(lblThetime);
        contentPane.add(lblThetime);
    }
}, 1000, 1000);

contentPane 被定义为 private JPanel contentPane;

这也不起作用,但是只有时间本身是空白的,窗口中的其余内容(另一个 JLabel(只是一些文本))保持正常。

没有任何刷新,它的行为如上所述,它只显示它开始的时间并永远保持那个时间。

我将 Eclipse 与 WindowBuilder 一起使用。 (而且我(可能很明显)完全是 Java GUI 的菜鸟 xD)

【问题讨论】:

    标签: java user-interface time clock windowbuilder


    【解决方案1】:

    我找到了解决方案!

    我在这里尝试了所有作为答案给出的解决方案,但没有一个可以使代码完全正常工作,但是所有答案都为我指明了正确的方向。我在一个忘记名字的网站上找到了问题的解决方案,但我使用了它的建议并提出了这个有效的最终解决方案:

            // New timer which works!
        int delay = 1000; //milliseconds
          ActionListener taskPerformer = new ActionListener() {
              public void actionPerformed(ActionEvent evt) {
                  String date = new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date(System.currentTimeMillis()));
                  lblThetime.setText(date);
              }
          };
          new Timer(delay, taskPerformer).start();
    

    感谢所有没有说答案的人,我可能无法找到这个解决方案:D

    【讨论】:

    • 您的问题是由于未使用 setText 而引起的 - 他清楚地指出了这一点。我也相信,既然他带领你更正了代码,他应该得到一些荣誉。
    • 因为它没有解决问题,它只是为我指明了正确的方向。 Warby 你会在 SO 中看到很多答案,它们只会将 OP 引向正确的方法,不要直接给出“工作代码”,因为目标是向同行学习,而不是让别人完成我们的工作。例如看到这个Q&APS: 谢谢@ChristianFries :)
    • 别担心,我们每天都在不断了解这个网站:P 我很高兴你自己解决了你的问题,而不是复制/粘贴别人的代码。保持这种方式! :D
    【解决方案2】:

    首先,您使用的是java.util.Timer 而不是javax.swing.Timer。在使用 Swing 组件时,您需要使用第二类,以确保在 Event Dispatch Thread 上进行 GUI 更新。也可以看看Concurrency in Swing 教程。

    正如其他答案中所建议的,每次您想要更新其文本时,都无需删除/添加JLabel。只需调用JLabel.setText() 方法即可。

    如果您仍想每次都删除/添加JLabel,请注意这一点:

    来自Container.add()javadoc:

    这个方法改变了布局相关的信息,因此, 使组件层次结构无效。 如果容器已经 显示后,必须验证层次结构,以便 显示添加的组件。

    然后你需要调用Component.revalidate() 方法。像这样:

    contentPane.remove(lblThetime);
    contentPane.add(lblThetime);
    contentPane.revalidate();
    

    【讨论】:

      【解决方案3】:

      您应该每秒更改标签的字符串,而不是删除标签并将其添加到面板。

      Timer timer = new Timer();
      timer.scheduleAtFixedRate(new TimerTask() {
          @Override
          public void run() {
             String date = new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date() );
      
             lblThetime.setText(date);
          }
      }, 1000, 1000);
      
      
      
      // Creating the panel...
      JLabel lblThetime = new JLabel(date);
      

      【讨论】:

        【解决方案4】:

        您可以尝试将 Swing Timer 用于该任务,例如:

        private static JLabel l;
        
        public static void main(String[] args) {
        
            Timer timer = new Timer(1000, new ActionListener() {
        
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    l.setText(new Date().toString());
                }
            });
            timer.start(); 
            JFrame f = new JFrame();
            l=new JLabel(new Date().toString());
            f.getContentPane().add(l);
        
            f.pack();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setVisible(true);
        }
        

        该示例每秒使用新日期更新 JLabel

        【讨论】:

          【解决方案5】:
          Timer timer = new Timer();
          timer.scheduleAtFixedRate(new TimerTask() {
              @Override
              public void run() {
                  label.setText(new Date().toString());
              }
          }, 1000, 1000);
          

          不是更简单吗?

          【讨论】:

            【解决方案6】:

            线索 1:真正在 Java 中搜索 Timer 类。你选对了吗?

            线索 2:改为更新标签文本。

            【讨论】:

            • 你好,Kili Liam。欢迎来到 SO 并感谢您的参与,但这不是 SO 的工作方式……在这里,您不应该用谜语和其他问题来回答问题,当然也不应该以“RTFM”风格提供“线索”。在这里,您用...回答问题!您也不应该以缩写为“HIH”的“Hope It Helps”或您的姓名缩写来结束您的答案。如果您不知道或不想给出正确答案,那么您根本就不要发帖。如果你想评论(而不是回答),你可以使用 cmets(一旦你获得了一些代表)。
            猜你喜欢
            • 2018-02-18
            • 2012-06-18
            • 2019-08-26
            • 2014-12-29
            • 1970-01-01
            • 1970-01-01
            • 2013-04-14
            • 2019-01-05
            • 1970-01-01
            相关资源
            最近更新 更多