2011-09-04 23 views
3

我對Java非常陌生(僅使用它一週左右),我正在開發商店模擬器。基本上我只想完成一些基本的工作,比如有一段時間直到關閉以及從屏幕上顯示打開的變量開始。javax.swing.JFrame setText()在循環中? +有意拖延?

我在我的模擬所作的以下功能延伸javax.swing.JFrame中類:

public void incOpenTime() { 
    timeOpen++; 
    int hours = timeOpen/3600; 
    int minutes = (timeOpen % 3600)/60; 
    int seconds = (timeOpen % 3600) % 60; 
    this.openTime.setText((hours < 10 ? "0" : "") + hours 
      + ":" + (minutes < 10 ? "0" : "") + minutes 
      + ":" + (seconds < 10 ? "0" : "") + seconds); 
    decTimeLeft(); 
    } 

public void decTimeLeft() { 
    int remainingTime = 28800 - timeOpen; 
    int hours = remainingTime/3600; 
    int minutes = (remainingTime % 3600)/60; 
    int seconds = (remainingTime % 3600) % 60; 
    this.timeLeft.setText((hours < 10 ? "0" : "") + hours 
      + ":" + (minutes < 10 ? "0" : "") + minutes 
      + ":" + (seconds < 10 ? "0" : "") + seconds); 

    } 

使用setText()方法的的OpenTime和的timeleft變量是GUI本身的一部分。

在主,我叫incOpenTime像這樣:

while(this.timeOpen < 28800) 
{ 
    incOpenTime(); 

} 

首先,當我運行這個它基本上只是經過循環,僅輸出最後一次在屏幕上。我將如何做到這一點,所以時代在不斷變化?

其次,我想稍微延遲...也許大約每秒1ms,以便模擬運行速度更慢,其他數據輸出到屏幕(更高版本)更具可讀性。我試過Thread.sleep(1);在循環中,但它不會在更改時顯示數字。

請幫忙。

感謝

編輯:

這裏就是我做得到它的工作。在主:

timer = new Timer(); 
for(int i=1; i<= 28800; i++) 
{ 
     timer.schedule(new task(), 1*i); 

} 

做了一個新的類:

class task extends TimerTask { 

    @Override 
    public void run() { 
     incOpenTime(); 
     } 
} 
+1

否 - 你需要一個javax.swing.Timer(就像trashgod建議 - 給他1+)而不是java.util.Timer。這裏有很大的不同,如果在你不期望的時候使用這種類型的Swing應用程序,那麼util Timer會在後面咬你。 –

回答

0

你需要一個java.util.Timer

編輯:由於這是公認的答案,但需要注意的是TimerTask應執行是重要的Runnable在事件分派線程上。在@ mKorbel的answer中記錄了此approach的正確變體。下面有一個簡短的例子和一個更詳細的例子here。 @Hovercraft提出的一個稍微簡單的方法見here

class Task extends TimerTask { 

    @Override 
    public void run() { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       incOpenTime(); 
      } 
     }); 
    } 
} 
+0

謝謝,我進行了更改,現在可以使用。請參閱原始發佈以查看修改。 – snotyak

+1

-1投票:你不應該爲需要javax.swing.Timer的情況推薦java.util.Timer。 util定時器可以並最終會中斷併發。 –

+0

@ mKorbel's [answer](http://stackoverflow.com/questions/7302353/javax-swing-jframe-settext-in-a-loop-intentional-delay/7302599#7302599)應該在應用時使用java.util .Timer'在這方面。回答編輯。 – trashgod

3

從BackGroung任務的輸出或線程的GUI未正確發佈到EDT,

你必須包裝任何輸出到GUI(從BackGroung任務或線程)的

invokeLater() 

如果方法可以再同步

invokeAndWait() 

請閱讀更多關於Concurency in Swing

5

javax.swing.Timer可能是一個不錯的選擇,因爲「在事件分派線程上執行Timers的動作事件處理程序」。有一個例子here

+1

@chickeneaterguy:這是正確的答案。 1+ –

+0

是與+1相同 – mKorbel

+0

+1使用Swing定時器而不是通用定時器來執行與GUI相關的任務。 – adatapost