[英]JavaFX: Binding Timeline's duration to a property
我有一個具有一些雙值的組合框的應用程序。 用戶可以選擇任何值。 該應用程序附加了一個“ TimeLine ”,它將在控制台上打印一個語句。 sscce在下面。 應該發生的是應該打印從組合框中選擇的選項的文本。 請建議。
package just.to.test;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TimerSample extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Text Fonts");
Group g = new Group();
Scene scene = new Scene(g, 150, 100);
ObservableList<Double> data = FXCollections.observableArrayList();
data.add(5.0);
data.add(10.0);
data.add(15.0);
data.add(20.0);
ComboBox<Double> timeOptions = new ComboBox<Double>(data);
timeOptions.getSelectionModel().selectFirst();
g.getChildren().addAll(timeOptions);
primaryStage.setScene(scene);
primaryStage.show();
final double timerInterval = timeOptions.getSelectionModel().getSelectedItem();
KeyFrame keyFrame = new KeyFrame(Duration.seconds(timerInterval),
new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("This is called every "
+ timerInterval + " seconds");
}
});
Timeline timerThread = new Timeline(keyFrame);
timerThread.setCycleCount(Timeline.INDEFINITE);
timerThread.play();
}
}
您無法將時間軸的持續時間綁定到屬性,因為時間軸中的關鍵幀的持續時間不是屬性,您只能將屬性綁定到屬性。
您需要做的是監聽組合框值的變化,並在用戶選擇新的持續時間時觸發創建具有新持續時間的新關鍵幀。 您也無法修改正在運行的時間軸的關鍵幀,因此您必須在設置時間軸的新關鍵幀之前停止時間軸,然后在設置新關鍵幀后啟動時間軸。
示例代碼
import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.collections.*;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.ComboBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TimerSample extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) {
Group g = new Group();
Scene scene = new Scene(g, 150, 100);
ComboBox<Double> timerOptions = createTimerOptions(
0.5, 1.0, 1.5, 2.0
);
g.getChildren().addAll(timerOptions);
createTimer(timerOptions);
stage.setScene(scene);
stage.show();
}
private ComboBox<Double> createTimerOptions(double... options) {
ObservableList<Double> data = FXCollections.observableArrayList();
for (Double option: options) {
data.add(option);
}
return new ComboBox<Double>(data);
}
private void createTimer(ComboBox<Double> timeOptions) {
final Timeline timer = new Timeline();
timer.setCycleCount(Timeline.INDEFINITE);
timeOptions.valueProperty().addListener(new ChangeListener<Double>() {
@Override
public void changed(ObservableValue<? extends Double> observable, Double oldValue, Double newValue) {
resetTimer(timer, newValue);
}
});
timeOptions.getSelectionModel().selectFirst();
}
private void resetTimer(Timeline timer, final double timerInterval) {
KeyFrame keyFrame = new KeyFrame(
Duration.seconds(timerInterval),
new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println(
"This is called every "
+ timerInterval
+ " seconds"
);
}
}
);
timer.stop();
timer.getKeyFrames().setAll(
keyFrame
);
timer.play();
}
}
只是想知道性能是否明顯更重,因為在組合框值的每個變化中添加一個新的關鍵幀。
在這種情況下,不要過分擔心性能 - 這是一種高效的操作。
除了創建新的關鍵幀之外沒有其他解決方案,因為關鍵幀是不可變對象 。
您可以在前面構建關鍵幀,或者在懶惰地構建它們時將它們放置在LRU緩存之類的東西中,但通常所涉及的額外復雜性幾乎肯定不值得。
所有動畫都有一個rateProperty()
,可以在正在運行的動畫中更改!
這似乎是一個更清潔的解決方案:
private void createTimer(ComboBox<Double> timeOptions) {
Timeline timer = new Timeline(
new KeyFrame(Duration.seconds(1),
evt-> System.out.println(
"This is called every "
+ timeOptions.getValue()
+ " seconds"
));
timer.setCycleCount(Timeline.INDEFINITE);
timer.rateProperty()
.bind(new SimpleDoubleProperty(1.0)
.divide(timeOptions.valueProperty()));
timeOptions.getSelectionModel().selectFirst();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.