JavaFX - 如何在ScrollPane中添加节点并确保正确的滚动方向

6
我在场景中有一个ScrollPane,并希望向其中添加一系列节点。具体数量必须是动态的。我已经使用Label节点测试了这个概念,可以成功地将尽可能多的Label添加到ScrollPane(目前是一个VBox)的内容中。
我的问题是如何允许用户正常滚动包含节点的ScrollPane。内容匹配滚动条的步伐;也就是说,当我向下滚动时,内容向下移动。我向上滚动,内容向上滚动。因此,如果我有10个标签,其中只有5个当前可见,那么查看其他5个的本能操作就是向下滚动。不幸的是,这只会将整个内容向下移动,暴露出顶部的空白区域并隐藏更多的标签。
如果需要,我可以发布一些示例代码,但我的攻击计划的要点如下:
ScrollPane sp = new ScrollPane();
VBox content = new VBox();
sp.setContent(content);
for (int i = 0; i < 10; i++)
{
    Label label = new Label("Label " + i);
    content.setPrefHeight(content.getPrefHeight() + label.getPrefHeight());
    content.getChildren().add(label);
}

由于我使用了一个 VBox,标签是堆叠在一起的(在 Y 轴方向上),这正是我想要的。随着越来越多的标签被添加,滚动条需要反映出 VBox 增加的大小。
我尝试过几种方法来解决这个问题,包括 ScrollPane.setVmax() 方法,它还不错,但我仍然有滚动方向移动内容的错误问题。我还尝试了使用 EventHandler 和 EventFilter 来相应地修改值,但仍无法解决滚动不朝着正确方向移动内容的问题。
答案似乎很简单,但即使在长时间的代码调试后,它仍然让我无从下手。
编辑:
jewelsea 的建议使用 ListView 解决了我的问题。然而,我仍然好奇为什么使用 ScrollPane 没有那么成功。此外,我在 ListView 实现中遇到了奇怪的行为:我使用一个按钮手动向视图添加新的 Label。偶尔,在添加新的 Label 后,视图会冻结。它会在几秒钟之内锁定,然后更新滚动位置或显示新添加的 Label。我不知道这是否因为视图中有约 20 个或更多的 Label 实例被管理,或者是否有其他更阴险的事情发生。

2
有什么理由不使用ListView来实现这个功能?我认为它可以为你处理这些问题。 - jewelsea
2
@jewelsea,你解决了!我总是惊讶于这些问题大多数看起来很复杂,但它们的解决方案却是如此简单。我能够使用ListView<Label>,并且仍然可以应用效果和变换(以动画方式添加Label)。通过CSS,我能够删除填充和颜色,模拟一个空区域,随着添加更多内容而保持可滚动状态。然而,我仍然很好奇为什么ScrollPane的滚动如此奇怪,为什么无论调整多少都无法修复它。 - CAG Gonzo
1个回答

1
关于滚动窗格问题,我知道你想做的是可能的,因为我正在做类似的事情。基于你上面给出的代码片段,我建议尝试以下几点:
  • 给ScrollPane设置一个首选高度和宽度以跟随。
  • 不要为内容VBox设置任何高度大小偏好,因为它将根据其内容增长。添加内容后无需更新其高度。
  • 使用VBox的setAlignment方法将其内容对齐到TOP_LEFTTOP_CENTERTOP_RIGHT
  • 在使用getPrefHeight()方法时要小心,因为如果你之前没有使用setPrefHeight(),我相信它会返回-1
希望这可以帮助你!

虽然上面的代码片段中没有显示,但我在 Scene Builder 和我的代码中明确设置了 ScrollPane 的尺寸。我还在内容的高度之间切换,并指定了对齐方式。经过一番折腾后,我成功添加了一些东西,但我仍然无法以我想要的方式滚动。 - CAG Gonzo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接