我有一个应用程序,它有一个带有一些双值的组合框。用户可以选择任何值。该应用程序附加了一个“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();
}
}
最佳答案
您不能将时间轴的持续时间绑定(bind)到属性,因为时间轴中关键帧的持续时间不是属性,您只能将属性绑定(bind)到属性。
您需要做的是监听组合框值的变化,并在用户选择新的持续时间时触发创建具有新持续时间的新关键帧。您也无法修改正在运行的时间线的关键帧,因此您必须在为时间线设置新关键帧之前停止时间线,然后在设置新关键帧后启动时间线。
示例代码
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();
}
}
在这种情况下不要太担心性能 - 这是一种高效的操作。
除了创建新的关键帧之外没有其他解决方案,因为关键帧是 immutable objects 。
您可以在前面构建关键帧,或者在懒惰地构建它们时将它们放置在类似 LRU cache 的东西中,但通常所涉及的额外复杂性几乎肯定不值得。
关于JavaFX : Binding Timeline's duration to a property,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19549852/