2016-12-03 4 views
1

私は、scenebuilderでJavaFXを使用してタイマーを作成しようとしていましたが、スレッドの作成にいくつか問題がありました。私がスタートボタンを押すたびに、アプリケーションは遅れてしまい、実際にテキストを更新することはありません。私はPlatform.runLater()を使用しようとしていますが、上記のようにすべてが遅れて結果としてです。ここでJavaFXのタイマーのスレッドの問題

はFXMLファイル上の特定のボタンにリンクされ、タイマーを制御する方法である:

@FXML 
private void startTimer(){ 
    System.out.println("started"); 
    stopWatch.startTimer(); 

} 

@FXML 
private void pauseTimer(){ 
    stopWatch.pauseTimer(); 
} 

@FXML 
private void stopTimer(){ 
    System.out.println("stopped"); 
    stopWatch.stopTimer(); 
} 

@FXML 
public void updateTimer(long dT){ 

    //System.out.println(((dT/6000)%1000)+":"+String.valueOf((dT/1000)%1000)+","+String.valueOf((dT)%1000)); 
    Platform.runLater(() ->{ 
     timer.setText(String.valueOf(dT/1000)); 
    }); 
} 

そして、ここではStopWatch.javaクラスです:

package sled.timer.address.model; 

import sled.timer.address.view.PersonOverviewController; 

public class StopWatch implements Runnable{ 

private Thread runThread; 
public boolean running = false; 
public boolean paused = false; 


private long summedTime = 0; 

PersonOverviewController personOverviewController; 

String time = ""; 

public void count(){ 

} 
public StopWatch(PersonOverviewController personOverviewController){ 
    this.personOverviewController = personOverviewController; 

} 
public void startTimer(){ 
    running = true; 
    paused = false; 

    runThread = new Thread(this); 
    runThread.start(); 
} 

public void pauseTimer(){ 
    paused = true; 
} 

public void stopTimer(){ 
    running = false; 
    paused = false; 
} 
@Override 
public void run() { 
    // TODO Auto-generated method stub 
    long startTime = System.currentTimeMillis(); 
    while(running && !paused){ 
     personOverviewController.updateTimer(summedTime + (System.currentTimeMillis() - startTime)); 
    } 
    if(paused) 
     summedTime += System.currentTimeMillis() - startTime; 

    else 
     summedTime = 0; 

} 

public long getSummedTime(){ 
    return summedTime; 
} 

すべてのヘルプは高く評価されます。

答えて

0

スレッドの更新頻度を制限しません。このようにして、アプリケーションスレッドが実行するために多くのメッセージを投稿します。イベント処理やレイアウトを行う時間がほとんどないため、アプリケーションをこのように動作させることができます。

さらに、ブーリアンフラグへのアクセスを同期化せず、volatileにしないでください。これは、値の変更が必ずしも他のスレッドから見えるとは限りません。

最後Runnableが開始されるまで代わりに、これ以上更新が掲載されていないことを確認する必要があります

private final Object updaterLock = new Object(); 
private final boolean updating = false; 
private final long value; 

public void updateTimer(long dT) { 
    synchronized (updaterLock) { 
     value = dT; 
     if (!updating) { 
      updating = true; 
      Platform.runLater(() -> { 
       synchronized (updaterLock) { 
        updating = false; 
        timer.setText(Long.toString(value/1000)); 
       } 
      }); 
     } 
    } 
} 
public class StopWatch implements Runnable{ 

    ... 

    public volatile boolean running = false; 
    public volatile boolean paused = false; 

をただし、更新を行うためにthe AnimationTimer classを使用することを検討してください。このクラスの更新頻度は限られています。