java - 绑定(bind)到 ScrollPane ScrollBar 时奇怪的 ScrollBar 行为

标签 java javafx javafx-8

我构建了一个控件,为 JavaFX 提供类似 Twitter Bootstrap 导航栏的行为。它基本上由一个 StackPane 和一个背面的 ScrollPane 组成,一个 BorderPane 和顶部的 Bottom 栏,最后一个 BorderPane 和一个 ScrollBar 在最顶层的右边。 这应该支持以下场景:

  • 在顶部和底部有固定元素,滚动时不会移动(导航栏)
  • 有一个位于内容顶部的滚动条,这与 ScrollPanes 将内容推到左侧的默认行为不同,以便为内置滚动条提供不动产

因此有了 StackPane 布局。

布局部分工作正常并且可以满足我的要求。不过,我的 ScrollBar 表现得很奇怪。当内容可滚动时, native ScrollBar(由 ScrollPane 管理的)如下所示:

native ScrollBar

红线表示拇指可能具有的最大尺寸的估计值。因此对于可滚动的内容,ScrollBar 不是越高越好,这是正确的。

现在,我的实现对可滚动内容的行为有所不同。我可以观察到两种行为:

enter image description here

ScrollBar thumb 很小,尽管原生的有正确的大小。或者:

enter image description here

尽管内容是可滚动的,但缩略图具有最大尺寸。 虽然滚动有效,但这两个示例在视觉效果方面显然是错误的。 我绑定(bind)两个 ScrollBars 属性的代码如下所示:

vScrollBar.valueProperty().bindBidirectional(scrollPane.vvalueProperty());
vScrollBar.maxProperty().bind(scrollPane.vmaxProperty());
vScrollBar.minProperty().bind(scrollPane.vminProperty());
nodeListChangeListener = c -> {
    ScrollBar hiddenScrollBar = getScrollBarFromScrollPane(scrollPane, Orientation.VERTICAL);
    if (hiddenScrollBar != null) {
        vScrollBar.visibleAmountProperty().bind(hiddenScrollBar.visibleAmountProperty());
        vScrollBar.blockIncrementProperty().bind(hiddenScrollBar.blockIncrementProperty());
        vScrollBar.unitIncrementProperty().bind(hiddenScrollBar.unitIncrementProperty());
        scrollPane.getChildrenUnmodifiable().removeListener(nodeListChangeListener);
    }
};
scrollPane.getChildrenUnmodifiable().addListener(nodeListChangeListener);

另一件值得一提的事情是,在我使用此控件的几乎所有其他地方,它的行为都是正确的。只有少数几个区域会发生这种情况,但我不明白它怎么可能仍然存在。


最后:我在这里缺少什么属性?考虑到我将 ScrollPane ScrollBar 中的所有这些属性绑定(bind)到我的自定义覆盖 ScrollBar (vScrollBar),两个 ScrollBar 的行为不应该相同吗?

最佳答案

(我假设 getScrollBarFromScrollPane(scrollPane, Orientation.VERTICAL); 调用 (ScrollBar)scrollPane.queryAccessibleAttribute(AccessibleAttribute.VERTICAL_SCROLLBAR);)

我不知道您是如何创建组件的,但是 hiddenScrollBar 很可能只是 null 并且可见的 ScrollBar 永远不会绑定(bind)到 ScrollPane 的 ScrollBar .

发生这种情况是因为 nodeListChangeListener 在创建 ScrollPaneSkin 期间但在属性 skin 之前收到通知已设置,因此无法访问滚动条。

要正确绑定(bind)滚动条,您可以向 skinProperty 添加一个监听器:

scrollPane.skinProperty().addListener(c -> {
    ScrollBar hiddenScrollBar = (ScrollBar)scrollPane.queryAccessibleAttribute(AccessibleAttribute.VERTICAL_SCROLLBAR);
    if (hiddenScrollBar != null) {
        bar.visibleAmountProperty().bind(hiddenScrollBar.visibleAmountProperty());
        bar.blockIncrementProperty().bind(hiddenScrollBar.blockIncrementProperty());
        bar.unitIncrementProperty().bind(hiddenScrollBar.unitIncrementProperty());
    }
});

关于java - 绑定(bind)到 ScrollPane ScrollBar 时奇怪的 ScrollBar 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50491389/

相关文章:

tableview - JavaFX TableView scrollTo() 导致错误的行开始编辑

java - 为什么 StringTokenizer.hasMoreTokens 不应该返回 true?

java - 如何在 JavaFX 中将 StringProperty 绑定(bind)到 ObjectProperty<Integer>?

java - java中如何将 'hashtags'的字符串转换为json?

JavaFX 2D 变换矩阵的仿射变换

java - 如何通过数学运算绑定(bind)两个 SimpleDoubleProperty?

mouseevent - 从一个节点获取 MOUSE_PRESSED 事件后,无法从任何其他 javafx 8 节点获取鼠标事件

JavaFX 与 Java Swing 在行业中的使用

java - 在GAE中更新持久对象时如何更新memcache中的数据

java - Java线程中的优先级