2017-02-22 74 views
2

我在Java应用程序,当通过点击的JButton,豆蔻位冻结和其开口后打开新jFrames(冷冻时间1-2分钟/ 3分钟)面临的一个问题。我找不到什么错。但是我对下面附加的代码有些怀疑。该代码用于获取系统时间和日期并显示所有jFrame。所以这段代码在所有jFrames中。现在我的问题是,这个冻结是由这个代码发生..?或者可能有其他原因。?如果这个代码有任何错误plz告诉我,也...我使用NEtbeans 8.2。提前致谢。jFrames被这段代码冻结了吗? (附代码):8.2 Netbeans的

代码:

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

} 

回答

0

您可能创建一个单独的线程,但所有的UI更新用根倒在AWT线程。因此,该线程非常频繁地调用jLbl_date.setText()jLbl_time.setText()方法实际上是直接阻止AWT线程。

尝试添加sleep(1000)jLbl_Time.setText()

+0

另外'setText'调用应该是'SwingUtilities.InvokeLater'ed。 –

+0

雅,它应该,纠正我,如果我错了,但AWT不限制像JavaFX多线程的用户界面访问。 – Subhranil

+0

@Subhranil,你的答案tnx。我尝试了你现在说的话。但ita显示错误。请你能修改我的代码并在这里评论...?它对我来说非常有用。 –

2

这两个电话:

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

对EDT(事件指派线程)的情况发生,因为GUI组件必须从EDT操作。你可以把它们放在EDT使用SwingUtilities包裹他们:

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);来解决此问题。

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

是withing的 actionPerformed - 方法的代码是在美国东部时间执行
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(); 

的摆动计时器照顾。它还有额外的优势,如果需要的话,它会协调事件 - 另一个机制来防止事件淹没EDT。

+0

你打我吧! +1 –

0

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

一个更好的解决办法是使用javax.swing.Timer一个稍短的间隔和更新用户界面从连接动作侦听器。

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负载。

+0

我添加了ur代码。但得到埃罗这JFrame的不运行,以及...它说“没有main方法” 这里连接方式你的代码在我的代码: –

+0

公共AdminStudent(){ 的initComponents(); 的ActionListener timerListener =新的ActionListener { 公共无效的actionPerformed(ActionEvent的E) { 日期d =新日期(); 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(); } –

+0

我错过了动作侦听器末尾的';' –