2016-10-04 66 views
0

我在這裏有一些代碼,就像我想要的那樣工作。所有這些都是我在代碼中確定的特定日期的秒數。我使用Thread.currentThread().sleep(1000);來更新一個JLabel,並保留當前時間直到日期。問題在於JLabel不會像預期的那樣每秒刷新一次。有時它每2秒更新一次,其他時間需要10秒更新。我相信這跟我打電話給我的方法有關,但我不確定如何使它更有效率。Thread.sleep效率()

下面是調用線程內更新JLabel中的方法的主要方法:

public static void main(String args[]) 
{ 
    initUI(); 
    try 
    { 
     while(true) 
     { 
      Thread.currentThread().sleep(1000); 
      getTime(); 
     } 
    } catch(Exception e){System.out.println("An error has occured...");} 
} 

這裏是由主要方法調用的方法調用的方法。這種方法最終將剩下的變量到3號的方法秒:

public static void getTime() 
{ 
    Calendar c = Calendar.getInstance(); 
    // Gets abstract current time in ms 
    long now = c.getTimeInMillis(); 

    c.set(Calendar.HOUR_OF_DAY, 0); 
    c.set(Calendar.MINUTE, 0); 
    c.set(Calendar.SECOND, 0); 
    c.set(Calendar.MILLISECOND, 0); 

    // Gets current time in ms 
    long msPassed = now - c.getTimeInMillis(); 
    // There are 86,400,000 milliseconds in a day 
    // Gets the seconds remaining in the day 
    long secRemaining = (86400000 - msPassed)/1000; 

    //-----------------------------------------------------// 
    // Creates a new calendar for today 
    Calendar cal = Calendar.getInstance(); 
    int currentDayOfYear = cal.get(Calendar.DAY_OF_YEAR); 

    // Creates a calendar for November 20th, 2016 
    Calendar aniv = new GregorianCalendar(2016,10,20); 
    aniv.set(Calendar.MONTH, 10); 
    aniv.set(Calendar.DAY_OF_MONTH, 20); 
    int aniversary = aniv.get(Calendar.DAY_OF_YEAR); 

    remaining = ((aniversary - currentDayOfYear) * 24 * 60 * 60) + secRemaining; 
    setTextOnScreen(remaining); 
} 

最後,這是改寫JLabel中的方法(通過上述方法調用):

public static void setTextOnScreen(long num) 
{ 
    text.setForeground(Color.GREEN); 
    text.setLocation((int)width/2 - 150, 50); 
    text.setFont(new Font("Monospaced", Font.BOLD, 48)); 
    text.setSize(300,150); 

    text.setText("" + num); 
    panel.add(text); 
} 

我不是包括代碼的其餘部分,因爲它應該是不相關的,但如果你也想看到這一點,請讓我知道。

+2

你的睡眠是2秒的javadoc –

回答

1

您應該只更新事件循環中的GUI組件。如果您嘗試在其他線程中更新它們,您可能會得到不可預知的結果。我建議使用swing Timer來定期在GUI事件循環中運行任務。

3

兩個問題:

  1. 你調用從後臺線程,這是不是你應該使用的UI線程text.setSomething()panel.add。嘗試使用SwingUtils.invokeLater()SwingUtils.invokeAndWait(),並在那裏調用接觸UI的代碼。

  2. 在調用set方法之後,還應該調用text.invalidate()來指示需要更新UI組件......否則UI線程將不會注意到組件需要重新測量和重新繪製。

0

你可以嘗試使用Timer

它有一個方法#scheduleAtFixedRate將接受執行任務,一時間開始執行它,並且它應該運行在任務的間隔。

將您的預定操作換成類別TimerTask以用於此方法。

下面是這個類在Java 7中https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html