2017-02-22 52 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

我錯過了動作偵聽器末尾的';' –