Как я могу центрировать ScrollPane, который оборачивает Canvas фиксированного размера в BorderPane? - PullRequest
1 голос
/ 19 июня 2019

В приложении JavaFX мне нужно центрировать Canvas фиксированного размера, обернутый StackPane, затем ScrollPane, внутри BorderPane. Проблема в том, что когда я включаю ScrollPane, дерево компонентов больше не центрируется в середине центральной области BorderPane. Одно из решений, которое я попробовал, - установить максимальный размер ScrollPane. Это работает (компоненты становятся центрированными), но создает другую проблему: когда область области просмотра недостаточна в каком-либо одном измерении (скажем, ширине), обе полосы прокрутки появятся в любом случае. Поскольку размер ScrollPane ограничен, дополнительное пространство, занимаемое полосой прокрутки в одном измерении, приведет к уменьшению области просмотра в другом измерении, а свойство максимального размера, необходимое для центрирования, не позволит выделять для него больше места.

Вот рабочая демонстрация проблемы:

public final class Minimal extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        Canvas canvas = new Canvas(200,200) {
            @Override
            public boolean isResizable() {
                return false;
            }
        };

        StackPane pane = new StackPane(canvas);
        pane.setStyle("-fx-border-insets: 4; -fx-border-style: solid;");
        ScrollPane scroll = new ScrollPane(pane);
        // scroll.setMaxSize(212, 212); // Imperfect Solution
        BorderPane root = new BorderPane();
        root.setCenter(scroll);
        stage.setScene(new Scene(root));
        stage.show();
    }   
}

С закомментированной строкой при изменении размера фрейм отображается как:

enter image description here

Если я установлю максимальный размер: тогда обе полосы прокрутки появляются одновременно (обратите внимание, что вертикальная полоса не нужна:

enter image description here

Самым близким, что я нашел, был этот вопрос , на который действительно нет ответа. К сожалению, это решение , которое, кажется, хорошо работает в Swing, похоже, ничего не делает, так как я уже использую оболочку (StackPane), и это не помогает. Я надеюсь, что есть решение, которое опирается исключительно на макеты, без необходимости возвращаться к написанию слушателей для событий изменения размера или привязки к свойствам размера и т. Д.

1 Ответ

2 голосов
/ 19 июня 2019

Пусть StackPane заполнит весь ScrollPane. StackPane будет центрировать холст для вас :

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

Таким образом, все, что вам нужно сделать, это установить свойства «fitTo…» ScrollPane, чтобы StackPane заполнил его:

scroll.setFitToWidth(true);
scroll.setFitToHeight(true);
...