JavaFX - horizontal marquee text

不想你离开。 提交于 2019-11-29 02:33:25

I have managed it to work, any recalculations can happen only after transition is stopped so we cannot set its cycleCount to Timeline.INDEFINITE. My requirement was that I could change text inside component so there are fxml wirings:

@FXML
private Text node; // text to marquee

@FXML
private Pane parentPane; // pane on which text is placed

The code which works is:

transition = TranslateTransitionBuilder.create()
        .duration(new Duration(10))
        .node(node)
        .interpolator(Interpolator.LINEAR)
        .cycleCount(1)
        .build();

transition.setOnFinished(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent actionEvent) {
        rerunAnimation();
    }
});

rerunAnimation();

where rerunAnimation() is:

private void rerunAnimation() {
    transition.stop();
    // if needed set different text on "node"
    recalculateTransition();
    transition.playFromStart();
}

and recalculateTransition() is:

private void recalculateTransition() {
    transition.setToX(node.getBoundsInLocal().getMaxX() * -1 - 100);
    transition.setFromX(parentPane.widthProperty().get() + 100);

    double distance = parentPane.widthProperty().get() + 2 * node.getBoundsInLocal().getMaxX();
    transition.setDuration(new Duration(distance / SPEED_FACTOR));
}

You should be able to do this by listening to your scene's widthProperty. You can either access this via newsFeedText.getScene().widthProperty() or get a reference from your main class and expose it from there or pass it to a method or constructor to access within your class that declares newsFeedText.

The benefit of this approach is that now your logic is dependent upon the width of your scene (a dynamic dependency) rather than the width of your monitor (a static dependency). Note that I have not tested this approach but at the moment see no reason (perhaps naively) it shouldn't work.

As for your duration dependency, you can solve that by performing some sort of calculation based on the length of the text in newsFeedText. Something like Duration.seconds(newsFeedText.get Text().length()/denominator) where denominator is some value you specify (such as 7500, as in your code). This will make your duration dynamically computed based on the length of your text.

If you want to operate with the width of newsFeedText itself, rather than the length of its text, then simply replace newsFeedText.getText().length() with newsFeedText.getWidth(). Ensure you perform this computation after newsFeedText has been laid out so a call to get its width returns the actual width. You can also replace the call with any of getPrefWidth(), getMinWidth(), or getMaxWidth().

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!