我如何将一个包含固定大小 Canvas 的 ScrollPane 居中放置在 BorderPane 中?

How can I center a ScrollPane that wraps a fixed-sized Canvas in a BorderPane?

在 JavaFX 应用程序中,我需要将一个由 StackPane 包裹的固定大小的 Canvas 居中,然后 ScrollPaneBorderPane 中居中。问题是当我包含 ScrollPane 时,组件树不再居中在 BorderPane 的中心区域的中间。我尝试的一种解决方案是修复 ScrollPane 的最大大小。这行得通(组件居中),但会产生一个不同的问题:当视口区域在任何一个维度(例如,宽度)上都不足时,无论如何都会出现两个滚动条。因为 ScrollPane 的大小是有界的,滚动条在一个维度上额外占用的 space 将导致视口在另一个维度上缩小,并且居中所需的最大尺寸 属性,将阻止为它允许更多 space。

这是该问题的工作演示:

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();
    }   
}

注释掉该行后,调整大小时,框架显示为:

如果我修复了最大尺寸:那么两个滚动条都会同时显示(注意垂直滚动条是不必要的:

我找到的最接近的是 this question, which does not really have an answer. Unfortunately, ,它似乎在 Swing 中运行良好,似乎没有做任何事情,因为我已经在使用包装器(StackPane),而且它不是帮助。我希望有一个完全依赖布局的解决方案,而不必恢复为调整大小事件或绑定到大小属性等编写侦听器。

让 StackPane 填满整个 ScrollPane。然后 StackPane 将 center the canvas for you:

The stackpane will attempt to resize each child to fill its content area. If the child could not be sized to fill the stackpane (either because it was not resizable or its max size prevented it) then it will be aligned within the area using the alignment property, which defaults to Pos.CENTER.

因此,您需要做的就是设置 ScrollPane 的“fitTo...”属性,这样 StackPane 就会填充它:

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