我正在尝试实现一个自定义滑块,其上方有一个矩形条,其中的线条代表某些时间点的事件,如下图所示。它基本上是滑块上方的时间线,该事件描绘为垂直线。
该图显示了滑块的起点(t = 0)和结束点(t = x)之间的14条垂直线。每一行对应一个任意事件和一些上下文信息。
滑块将实时播放,即拇指将以实时速度沿其轨道移动。当滑块传递事件的指定时间时,它将在文本区域中打印事件的上下文信息。使用该图表,当前正在显示14秒事件的信息。
问题: 1.如何让拇指实时移动? 2.如何检测拇指已到达事件并因此触发在文本区域触发新输出的事件?
我的方法是处理所有事件并为每个事件创建一个计时器,以便在相关时间触发。这似乎相当不优雅。并且将来需要能够将拇指拖动到任何时间点,并且每次发生时都必须创建计时器事件,这似乎非常低效。
我正在使用JavaFX,所以我想尽可能地利用属性绑定。我在Java 8之前有很多经验,但这是我第一次愤怒地使用Java 8。
谢谢。
答案 0 :(得分:1)
您可以使用Timeline
中的Animation API来执行此操作。
简而言之:
public class TimelineEvent {
private final Duration time ;
private final String info ;
public TimelineEvent(Duration time, String info) {
this.time = time ;
this.info = info ;
}
public Duration getTime() {
return time ;
}
public String getInfo() {
return info ;
}
}
int maxSeconds = ... ;
TimelineEvent[] events = ... ; // populate array of events...
Slider slider = new Slider(0, maxSeconds, 0);
TextArea textArea = new TextArea();
// ...
Timeline timeline = new Timeline();
for (TimelineEvent event : events) {
timeline.getKeyFrames().add(new KeyFrame(event.getTime(),
e -> textArea.setText(event.getInfo());
}
// make slider value change with timeline:
timeline.getKeyFrames().add(new KeyFrame(Duration.ZERO,
new KeyValue(slider.valueProperty(), 0)));
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(maxSeconds),
new KeyValue(slider.valueProperty(), maxSeconds)));
timeline.play();
另一种选择,如果用户要手动移动滑块,可能会更方便。 (以及动画制作),只是使用动画移动滑块,然后在滑块的值上使用侦听器或绑定:
int maxSeconds = ... ;
Slider slider = new Slider(0, maxSeconds, 0);
TextArea textArea = new TextArea();
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(slider.valueProperty(),0)),
new KeyFrame(Duration.seconds(maxSeconds), new KeyValue(slider.valueProperty(),maxSeconds)));
textArea.textProperty().bind(Bindings.createStringBinding(
() -> findInfoForTimepoint(slider.getValue()),
slider.valueProperty()));
与
private String findInfoForTimepoint(double seconds) {
// figure and return correct "info" for given time in seconds...
}