2016-11-07 68 views
1

我試圖實現一個自定義滑塊上面的矩形條帶有代表事件在某些時間點的事件,如下圖所示。它基本上是一個滑塊上方的時間線,該事件描述爲垂直線。JavaFX時間線播放滑塊觸發事件在異步時間點

enter image description here

圖顯示在滑塊的開始(t = 0時)和終點(T = X)14條之間的垂直線。每行對應一個任意事件和一些上下文信息。

滑塊將實時播放,即拇指將以實時速度沿其軌道移動。當滑塊通過事件的指定時間時,它將在文本區域中打印事件的上下文信息。使用該圖,當前正在顯示14秒鐘的事件信息。

問題: 1.如何使拇指實時移動? 2.如何檢測到拇指已到達事件並因此觸發在文本區域觸發新輸出的事件?

我的方法是處理所有事件併爲每個事件創建一個計時器以在關聯的時間觸發。這似乎相當不雅。未來的需求是能夠將拇指拖動到任何時間點,並且每次發生計時器事件似乎都非常低效。

我正在使用JavaFX,所以我想盡可能地利用屬性綁定。我在Java 8之前有大量的經驗,但這是我第一次憤怒地使用Java 8。

謝謝。

回答

1

您可以使用Animation APITimeline進行此操作。

簡言之:

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... 
} 
+0

感謝您的建議James_D。第一個是非常優雅的地方,每個事件都設置爲一個KeyFrame,當相應的時間流逝時觸發。第二種方法也很好,但是,bind語句會在每個滑塊值更改上運行,這意味着findInfoForTimepoint()會運行很多次,這是不可取的。 所以我傾向於第一個建議。然而,我試圖修改它在播放過程中移動拇指,但由於某些原因,我不能。有沒有辦法將拇指拉回到某一點,然後繼續播放,而KeyFrame事件仍然有效? – emjay