这个代码冻结了jFrames? (附代码):Netbeans 8.2

时间:2017-02-22 14:44:17

标签: java freeze netbeans-8.2

我在我的java应用程序中遇到一个问题,当通过单击jButton打开新的jFrame时,litte-bit冻结并在其打开之后(冻结时间为1-2分钟/ 3分钟)。我无法找到最新的错误。但我对以下附加代码有一些疑问。用于获取系统时间和日期并显示所有jFrame的代码。所以这段代码在所有jFrame中。现在我的问题是,这个代码冻结了吗?或者可能有任何其他原因..?如果这段代码有任何错误,请告诉我也是......我使用的是NEtbeans 8.2。提前谢谢。

代码:

public AdminHome() {
    initComponents();

    new Thread(new Runnable() {
        @Override
        public void run() {

            while (true) {
            Date d=new Date();

            SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd");
            String s =  sd.format(d);
            String s1 = d.toString();
            String ar[]=s1.split(" ");

            jLbl_Date.setText(s);  
            jLbl_Time.setText(ar[3]);
            }  
        }
    }).start();

}

2 个答案:

答案 0 :(得分:2)

这两个电话:

jLbl_Date.setText(s);  
jLbl_Time.setText(ar[3]);

必须在EDT(事件调度线程)上发生,因为必须从EDT操纵GUI组件。您可以使用SwingUtilities包装它们将它们放在EDT上:

SwingUtilities.invokeLater(() -> {
    Date d=new Date();

    SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd");
    String s =  sd.format(d);
    String s1 = d.toString();
    String ar[]=s1.split(" ");

    jLbl_Date.setText(s);  
    jLbl_Time.setText(ar[3]);
});

然而,仍然存在问题。由于您的线程在更新标签之间没有睡眠,因此您将使用更新请求充斥EDT,从而导致GUI再次冻结。您可以在更新标签后添加Thread.sleep(1000);来解决此问题。

更优雅的方法是使用swing计时器而不是你的线程:

Timer timer = new Timer(1000, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            Date d=new Date();

            SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd");
            String s =  sd.format(d);
            String s1 = d.toString();
            String ar[]=s1.split(" ");

            jLbl_Date.setText(s);  
            jLbl_Time.setText(ar[3]);
        }
});            
timer.setInitialDelay(0);
timer.start();

swing计时器注意在EDT上执行带有actionPerformed - 方法的代码。如果需要的话,它还有额外的优势,它可以使事件变得更好 - 这是防止事件泛滥EDT的另一种机制。

答案 1 :(得分:0)

看起来您已经创建了一个线程来运行无限循环来更新某些日期和时间字段。这不是实现您想要做的事情的好方法。

更好的解决方案是使用间隔较短的javax.swing.Timer并从附加的动作侦听器更新UI。

ActionListener timerListener = new ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        Date d=new Date();

        SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd");
        String s =  sd.format(d);
        String s1 = d.toString();
        String ar[]=s1.split(" ");

        jLbl_Date.setText(s);  
        jLbl_Time.setText(ar[3]);
    }
};

Timer t = new javax.swing.timer(1000, timerListener).start();

像上面这样的东西应该可以解决问题。这样可以省去跨越线程边界以更新UI的麻烦,并且可以大大减少以前的解决方案中的CPU负载。