2016-08-04 9 views
1

タイムラインを使用して1分の時間を記録するシステムを作成しようとしています。このような状況では、タイムラインを1秒ごとに増やして、アクションバーを起動してタイムラインをリセットする前に、Progressbarに1分前にこれを記録させたいと思います。JavaFXタイムラインを秒単位で取得してプログレスバーにバインドするにはどうすればよいですか?

final Timeline timeline = new Timeline(); 
timeline.setCycleCount(Animation.INDEFINITE); 
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(1))); 
progress.progressProperty().bind(timeline.getTotalDuration()???); 
timeline.play(); 

私はタイムラインサイクルが決して止まらないようにサイクルカウントを不定に設定しました。また、Progressbarプロパティをタイムラインにバインドしようとしましたが、Observablevalueが必要です(timeline#getTotalDurationは提供していません)。

私は別々のスレッドに結合することなくプログラムを実行しようとしました:

new Thread(new Task<Void>() { 
      @Override 
      protected Void call() throws Exception { 
       while(true){ 
        System.out.printf("s:\t%f\n",timeline.getTotalDuration().toSeconds()); 
        Thread.sleep(1000); 
       } 
      } 
}).start(); 

しかし、これは毎秒タイマーを増やし、代わりに一度だけで、すべてのサイクルを通過しない実行されています。私が設定したcycleCountはINDEFINITEだったので、#totalDurationの結果はinfiniteです。

秒単位でタイムラインを取得するにはどうすればよいでしょうか?また、100%に達するまでプログレスバーにデュレーションをバインドして特別なアクションを呼び出せるようにするにはどうすればいいですか?あなたはちょうどそれが毎分の終わりに達したときにプログレスバーが分にわたって完全なゼロから繰り返し増加し、コードを実行したい場合は

答えて

4

、あなたが必要なのは、次のとおりです。

ProgressBar progress = new ProgressBar(); 
    Timeline timeline = new Timeline(
     new KeyFrame(Duration.ZERO, new KeyValue(progress.progressProperty(), 0)), 
     new KeyFrame(Duration.minutes(1), e-> { 
      // do anything you need here on completion... 
      System.out.println("Minute over"); 
     }, new KeyValue(progress.progressProperty(), 1))  
    ); 
    timeline.setCycleCount(Animation.INDEFINITE); 
    timeline.play(); 

ことプログレスバーの「アナログ」エフェクトが作成されます。つまり、1秒ごとに段階的に増加するのではなく、1分間にスムーズに増加します。あなたが本当にインクリメンタル秒ごとに増加させたい場合は

、秒数を表すためにIntegerPropertyを使用し、それにプログレスバーの進捗プロパティをバインド:

ProgressBar progress = new ProgressBar(); 
    IntegerProperty seconds = new SimpleIntegerProperty(); 
    progress.progressProperty().bind(seconds.divide(60.0)); 
    Timeline timeline = new Timeline(
     new KeyFrame(Duration.ZERO, new KeyValue(seconds, 0)), 
     new KeyFrame(Duration.minutes(1), e-> { 
      // do anything you need here on completion... 
      System.out.println("Minute over"); 
     }, new KeyValue(seconds, 60)) 
    ); 
    timeline.setCycleCount(Animation.INDEFINITE); 
    timeline.play(); 

ここでのポイントIntegerPropertyを補間することです0から60までの整数値を受け入れます(つまり、補間値をintに切り捨てます)。ここ

は、第二のバージョンとSSCCEある:

import javafx.animation.Animation; 
import javafx.animation.KeyFrame; 
import javafx.animation.KeyValue; 
import javafx.animation.Timeline; 
import javafx.application.Application; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.ProgressBar; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 
import javafx.util.Duration; 

public class OneMinuteTimer extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     ProgressBar progress = new ProgressBar(); 
     progress.setMinWidth(200); 
     progress.setMaxWidth(Double.MAX_VALUE); 
     IntegerProperty seconds = new SimpleIntegerProperty(); 
     progress.progressProperty().bind(seconds.divide(60.0)); 
     Timeline timeline = new Timeline(
      new KeyFrame(Duration.ZERO, new KeyValue(seconds, 0)), 
      new KeyFrame(Duration.minutes(1), e-> { 
       // do anything you need here on completion... 
       System.out.println("Minute over"); 
      }, new KeyValue(seconds, 60)) 
     ); 
     timeline.setCycleCount(Animation.INDEFINITE); 
     timeline.play(); 

     StackPane root = new StackPane(progress); 
     root.setPadding(new Insets(20)); 
     primaryStage.setScene(new Scene(root)); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
関連する問題