JavaFX时间轴播放滑块在异步时间点触发事件

JavaFX时间轴播放滑块在异步时间点触发事件,java,asynchronous,javafx,timeline,Java,Asynchronous,Javafx,Timeline,我试图实现一个自定义滑块,上面有一个矩形条带,其中的线表示特定时间点的事件,如下图所示。它基本上是滑块上方的时间线,该事件被描述为垂直线 该图显示了滑块起点(t=0)和终点(t=x)之间的14条垂直线。每行对应一个任意事件和一些上下文信息 滑块将实时播放,即拇指将以实时速度沿其轨迹移动。当滑块经过事件的指定时间时,它将在文本区域中打印事件的上下文信息。使用图表,当前显示14秒时事件的信息 问题: 1.如何使拇指实时移动? 2.如何检测thumb已到达一个事件,从而触发一个触发文本区域新输出的事

我试图实现一个自定义滑块,上面有一个矩形条带,其中的线表示特定时间点的事件,如下图所示。它基本上是滑块上方的时间线,该事件被描述为垂直线

该图显示了滑块起点(t=0)和终点(t=x)之间的14条垂直线。每行对应一个任意事件和一些上下文信息

滑块将实时播放,即拇指将以实时速度沿其轨迹移动。当滑块经过事件的指定时间时,它将在文本区域中打印事件的上下文信息。使用图表,当前显示14秒时事件的信息

问题: 1.如何使拇指实时移动? 2.如何检测thumb已到达一个事件,从而触发一个触发文本区域新输出的事件

我的方法是处理所有事件,并为每个事件创建一个计时器,以便在相关时间触发。这似乎有点不雅。未来还需要能够将拇指拖到任意时间点,并且每次发生时都必须创建计时器事件,这似乎非常低效

我正在使用JavaFX,因此我希望尽可能多地利用属性绑定。我在Java8之前有很多经验,但这是我第一次愤怒地使用Java8

谢谢。

您可以使用中的

简言之:

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 = ... ;
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()));


感谢James_D的建议。第一个非常优雅,每个事件都设置为一个关键帧,当相应的时间流逝时触发。第二种方法也不错,但是,bind语句会在每次滑块值更改时运行,这意味着findInfoForTimepoint()会运行很多不需要的代码。所以我倾向于第一个建议。不过,我试图修改它,以便在播放过程中移动拇指,但由于某些原因,我无法。有没有办法将拇指拉回到某个点,然后在关键帧事件仍处于tact状态的情况下恢复播放?
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...
}