Странное поведение ScrollBar при привязке к ScrollPane ScrollBar - PullRequest
0 голосов
/ 23 мая 2018

Я создал элемент управления, обеспечивающий поведение, напоминающее навигационную панель Twitter Bootstrap, для JavaFX.В основном он состоит из StackPane с ScrollPane на задней панели, BorderPane с Top, Bottom bars сверху и, наконец, BorderPane с ScrollBar справа на самом верхнем слое.Предполагается, что он поддерживает следующие сценарии:

  • Имеют фиксированные элементы сверху и снизу, которые не перемещаются при прокрутке (по меню)
  • Имеют панель прокрутки сверхусодержимого в отличие от поведения по умолчанию ScrollPanes для перемещения содержимого влево, чтобы обеспечить пространство для встроенного ScrollBar

Отсюда макет StackPane.

Макетчасть отлично работает и делает то, что я хочу.Мой ScrollBar ведет себя очень странно, хотя.Когда содержимое прокручивается, нативная панель прокрутки (управляемая ScrollPane) выглядит следующим образом:

native ScrollBar

Красные линии указывают оценку максимального размерабольшой палец мог иметь.Так что с прокручиваемым контентом ScrollBar не настолько высок, насколько это возможно, что правильно.

Теперь моя реализация ведет себя по-другому с прокручиваемым контентом.Я могу наблюдать два поведения:

enter image description here

Ползунок ScrollBar является крошечным, хотя у родного есть правильный размер.Или:

enter image description here

Большой палец имеет максимальный размер, даже если содержимое прокручивается.Хотя прокрутка работает, оба эти примера явно неверны в отношении визуальных элементов.Мой код, который связывает два свойства 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);

Еще одна вещь, о которой стоит упомянуть, это то, что почти во всех других местах, где я использую этот элемент управления, он ведет себя правильно.Есть только несколько областей, где это происходит, но я не понимаю, как это все еще возможно.


Итак, наконец: Какое свойство мне здесь не хватает?Разве оба ScrollBars не должны вести себя одинаково, учитывая, что я связываю все эти свойства из ScrollPane ScrollBar с моим настраиваемым оверлеем ScrollBar (vScrollBar)?

1 Ответ

0 голосов
/ 28 мая 2018

(я предполагаю, что getScrollBarFromScrollPane(scrollPane, Orientation.VERTICAL); вызывает (ScrollBar)scrollPane.queryAccessibleAttribute(AccessibleAttribute.VERTICAL_SCROLLBAR);)

Я не знаю, как вы создаете свой компонент, но очень вероятно, что hiddenScrollBar это просто null, а видимый ScrollBarникогда не привязывается к полосе прокрутки панели прокрутки.

Это происходит потому, что nodeListChangeListener уведомляется во время создания ScrollPaneSkin, но до того, как установлено свойство skin, это невозможнодля доступа к полосе прокрутки.

Чтобы правильно привязать полосу прокрутки, вы можете добавить прослушиватель для 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());
    }
});
...