2016-10-04 2 views
0

ここに私が望むように動作するコードが少しあります。それはすべて、私がコードで決めた特定の日付までの秒単位のカウントダウンです。私はThread.currentThread().sleep(1000);を使って、日付まで残った現在の時間でJLabelを更新しています。問題は、JLabelが想定されているように毎秒リフレッシュしないことです。場合によっては2秒ごとに更新され、それ以外の場合は更新に10秒かかります。私はそれが私の方法をどのように呼んでいるかとは関係があると信じていますが、それをより効率的にする方法はあまりよく分かりません。ここでThread.sleep()での効率

は、スレッド内のJLabelを更新するメソッドを呼び出すmainメソッドである:ここでは

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...");} 
} 

はメインメソッドから呼び出されるメソッドによって呼び出されるメソッドです。このメソッドは、最終的には第三の方法に変数を残りの秒を送信します。

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

であります –

答えて

1

イベントループでGUIコンポーネントを更新する必要があります。他のスレッドでそれらを更新しようとすると、予期しない結果が得られます。私は定期的な仕事のためのスイングタイマーを使用してGUIイベントループで実行することをお勧めします。

3

2つの問題:あなたはあなたが使用する必要があるUIスレッドではありませんバックグラウンドスレッドからtext.setSomething()panel.addを呼んでいる

  1. SwingUtils.invokeLater()またはSwingUtils.invokeAndWait()を使用して、そこにUIに接触するコールコードを試してみてください。

  2. あなたsetメソッドを呼び出した後、あなたはまた、それ以外の場合は、UIスレッドは、コンポーネントが再測定し、再描画する必要があることを気付くことはありません... UIコンポーネントを更新する必要があることを知らせるためにtext.invalidate()を呼び出す必要があります。

0

あなたはそれを実行するためのタスク、それを実行開始する時間、およびそれからタスクを実行する必要があることを間隔を受け入れる方法#scheduleAtFixedRateを持ってTimer

を使用して試みることができます。

TimerTaskに拡張されたクラスにスケジュールされたアクションをラップして、このメソッドで使用します。ここで

は、このクラスのjavadocは、あなたの睡眠が2秒間でのJava 7 https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html