JavaFX-水平选框文本
我试图达到类似于在水平轴上移动的长文本行的效果。我设法使它工作,但我不能说它令人满意 我的JavaFX-水平选框文本,java,javafx,javafx-2,marquee,Java,Javafx,Javafx 2,Marquee,我试图达到类似于在水平轴上移动的长文本行的效果。我设法使它工作,但我不能说它令人满意 我的控制器类如下所示: @FXML private Text newsFeedText; (...) @Override public void initialize(URL url, ResourceBundle resourceBundle) { TranslateTransition transition = TranslateTransitionBuilder.create()
控制器
类如下所示:
@FXML
private Text newsFeedText;
(...)
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
TranslateTransition transition = TranslateTransitionBuilder.create()
.duration(new Duration(7500))
.node(newsFeedText)
.interpolator(Interpolator.LINEAR)
.cycleCount(Timeline.INDEFINITE)
.build();
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int width = gd.getDisplayMode().getWidth();
transition.setFromX(width);
transition.setToX(-width);
transition.play();
}
newsFeedText
绑定到某个动态更新的文本源,因此它包含不同数量的文本
我的代码至少有两个缺点:
- 从
过渡到-width
<代码>宽度是监视器的分辨率宽度+width
newsFeedText
width将大于监视器的分辨率宽度,则过渡将“一分为二”消失(仍在屏幕上)
- 当前,
不依赖于持续时间
的宽度新闻提要文本
fromX
和toX
,那么它将产生不同的选框速度
如何消除这些缺点?您应该能够通过收听场景的
widthProperty
来做到这一点。您可以通过newsFeedText.getScene().widthProperty()
访问它,或者从主类中获取一个引用并从那里公开它,或者将它传递给一个方法或构造函数,以便在声明newsFeedText
的类中进行访问
这种方法的好处是,现在您的逻辑取决于场景的宽度(动态依赖项),而不是监视器的宽度(静态依赖项)。请注意,我还没有测试过这种方法,但目前看不出它不起作用的原因(可能是天真的)
至于持续时间依赖关系,可以根据newsFeedText
中的文本长度执行某种计算来解决。类似于Duration.seconds(newsFeedText.get Text().length()/deminator)
的内容,其中deminator
是您指定的某个值(例如7500,如代码中的值)。这将根据文本的长度动态计算持续时间
如果要使用
newsFeedText
本身的宽度而不是文本的长度进行操作,只需将newsFeedText.getText().length()
替换为newsFeedText.getWidth()
。确保在布局了newsFeedText
之后执行此计算,以便调用获取其宽度返回实际宽度。您还可以使用getPrefWidth()
、getMinWidth()
或getMaxWidth()
中的任何一个替换调用。我已设法使其工作,任何重新计算只能在转换停止后进行,因此我们无法将其循环计数设置为时间线。不确定的。我的要求是我可以更改组件内的文本,以便有fxml连接:
@FXML
private Text node; // text to marquee
@FXML
private Pane parentPane; // pane on which text is placed
有效的守则是:
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();
而重新计算Transition()
是:
private void rerunAnimation() {
transition.stop();
// if needed set different text on "node"
recalculateTransition();
transition.playFromStart();
}
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));
}
这是另一个问题出现的地方,如果绑定TranslateTransition#toX
,调用TranslateTransition#play
并更改窗口大小,则在停止并再次播放之前,transition不会更改其toX
。在我的例子中,代码是在Initializable#initialize
方法中调用的,因此此时我的场景的大小等于零。请使用在width属性上注册的ChangeListener
。在那里,将您的转换值设置为<代码> ChangeListener 所报告的新值。考虑将MouQee控件捐赠给它。它在所有窗口宽度内工作,但如果我需要内部控件,怎么办?我无法隐藏文本particulary@jewelsea我认为我的“解决方案”效率太低,但在空闲的时候,我一定会改进它并捐赠解决方案。也考虑在矩形框文本下放置一个矩形形状,其大小大于可见屏幕区域,以实现平滑动画。文本形状必须在该矩形的所有路径上运行。不要忘记设置形状的缓存。