Java 绑定到滚动窗格滚动条时出现奇怪的滚动条行为

Java 绑定到滚动窗格滚动条时出现奇怪的滚动条行为,java,javafx,javafx-8,Java,Javafx,Javafx 8,我构建了一个控件,为JavaFX提供类似Twitter引导navbar的行为。它基本上由一个背面有滚动条的StackPane、一个顶部有顶部和底部条的BorderPane以及最后一个顶部层右侧有滚动条的BorderPane组成。 这应该支持以下场景: 在顶部和底部有固定的元素,滚动时不会移动(如同导航栏) 与滚动窗格的默认行为不同,在内容顶部有一个滚动条将内容向左推,以便为内置滚动条提供不动产 因此,StackPane布局 布局部分工作正常,符合我的要求。不过,我的滚动条的行为非常奇怪。当内

我构建了一个控件,为JavaFX提供类似Twitter引导navbar的行为。它基本上由一个背面有滚动条的StackPane、一个顶部有顶部和底部条的BorderPane以及最后一个顶部层右侧有滚动条的BorderPane组成。 这应该支持以下场景:

  • 在顶部和底部有固定的元素,滚动时不会移动(如同导航栏)
  • 与滚动窗格的默认行为不同,在内容顶部有一个滚动条将内容向左推,以便为内置滚动条提供不动产
因此,StackPane布局

布局部分工作正常,符合我的要求。不过,我的滚动条的行为非常奇怪。当内容可滚动时,本机滚动条(由滚动窗格管理的滚动条)如下所示:

红线表示对拇指最大尺寸的估计。因此,对于可滚动内容,滚动条没有尽可能高,这是正确的

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

滚动条拇指很小,即使本地拇指的大小正确。或:

即使内容可滚动,拇指的大小也最大。 虽然滚动是有效的,但这两个例子在视觉效果方面显然都是错误的。 绑定两个滚动条属性的代码如下所示:

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绑定到我的自定义覆盖滚动条(
vScrollBar
),这两个滚动条的行为不应该相同吗?
(我假设
getScrollBarFromScrollPane(ScrollPane,Orientation.VERTICAL);
调用
(ScrollBar)ScrollPane.queryAccessibleAttribute(AccessibleAttribute.垂直滚动条);

我不知道如何创建组件,但很可能
hiddenScrollBar
只是
null
,可见的滚动条永远不会绑定到滚动窗格的滚动条

这是因为在创建
ScrollPaneSkin
时,在设置属性之前,会通知
nodeListChangeListener
,因此无法访问滚动条

要正确绑定滚动条,可以将侦听器添加到
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());
    }
});

请添加一个组件的创建方式以及
getScrollBarFromScrollPane()
的功能。还要验证
hiddenScrollBar
是否为
null
。很抱歉回复太晚,今天才访问了该代码。这成功了,谢谢!