Canvas 的嵌套 BorderPane 只会增长,不会缩小

Nested BorderPane with Canvas only grows, never shrinks

我有一个包含 Canvas 的 BorderPane,其中 Canvas' 高度和宽度属性绑定到 BorderPane 的属性。 BorderPane 又是场景的根。

一切正常。如果我调整 window 的大小,BorderPane 的大小会更改以匹配场景的大小,并且 Canvas 会更改以匹配 BorderPane 的大小。

但是,如果我引入另一个 BorderPane,它就会停止工作:内部 BorderPane 和 Canvas 会随着 Scene 和外部 BorderPane 的增长而增长,但是当我缩小 window 时,它们不会收缩。

  Working:            Not working:

 ┌──────────────┐    ┌────────────────┐
 │    Scene     │    │     Scene      │
 │┌────────────┐│    │┌──────────────┐│
 ││ BorderPane ││    ││  BorderPane  ││
 ││┌──────────┐││    ││┌────────────┐││
 │││  Canvas  │││    │││ BorderPane │││
 ││└──────────┘││    │││┌──────────┐│││
 │└────────────┘│    ││││  Canvas  ││││
 └──────────────┘    │││└──────────┘│││
                     ││└────────────┘││
                     │└──────────────┘│
                     └────────────────┘

有效代码:

BorderPane parent = new BorderPane();
Canvas canvas = new Canvas();
canvas.widthProperty().bind(parent.widthProperty());
canvas.heightProperty().bind(parent.heightProperty());
parent.setCenter(canvas);
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.show();

无效的代码:

BorderPane inner = new BorderPane();

Canvas canvas = new Canvas();
canvas.widthProperty().bind(inner.widthProperty());
canvas.heightProperty().bind(inner.heightProperty());
inner.setCenter(canvas);

BorderPane outer = new BorderPane();
outer.setCenter(inner);

Scene scene = new Scene(outer);
stage.setScene(scene);
stage.show();

我添加了一些日志记录来确认问题:

# scene, outer pane, inner pane, and canvas growing
outer width: 1364.0 -> 1374.0
scene width: 1364.0 -> 1374.0
outer height: 339.0 -> 342.0
scene height: 339.0 -> 342.0
canvas width: 1364.0 -> 1374.0
inner width: 1364.0 -> 1374.0
canvas height: 339.0 -> 342.0
inner height: 339.0 -> 342.0
# scene and outer pane shrinking, canvas and inner not
outer width: 1374.0 -> 1327.0
scene width: 1374.0 -> 1327.0
outer height: 342.0 -> 330.0
scene height: 342.0 -> 330.0
outer width: 1327.0 -> 1290.0
scene width: 1327.0 -> 1290.0
outer height: 330.0 -> 326.0
scene height: 330.0 -> 326.0

显然,在这个玩具示例中,我可以只删除中间的 BorderPane,但是如果我想制作一个可重用、可调整大小的组件来包装 Canvas 怎么办?我怎样才能确保它总是用 parent 调整大小?无论如何,嵌套的 BorderPanes 是怎么回事?

Canvas 是不可调整大小的节点。这意味着它的大小是其父级 min 大小的下限。

如果您使用 BorderPane 作为场景根,调整 window 大小会强制调整场景大小,调整场景大小会强制调整场景根大小以适应 window .由于这个原因,Canvas 的父级缩小到它的 min 尺寸以下,Canvas 也缩小。

如果您将 BorderPane 缩小到它的 min 大小以下,它不会强制其可调整大小的子项调整到它们的 min 大小以下,而是将它们的大小设置为 min 尺寸代替。这样,包裹在 BorderPane 中的 BorderPane 永远不会被迫缩小到 Canvas 的大小以下,并且 Canvas 永远不会缩小。

您可以通过将 Canvasmanaged 属性 设置为 false 来解决此问题,这会导致计算 Canvas 时不考虑min 大小。 (请注意,布局根本不考虑非托管子级。因此,您应该将 Canvas 包装在 Pane 中作为唯一的子级,以防止对兄弟姐妹产生不良影响。)

Canvas canvas = ...
canvas.setManaged(false);
Pane canvasParent = new Pane(canvas);
canvas.widthProperty().bind(canvasParent.widthProperty());
canvas.heightProperty().bind(canvasParent.heightProperty());

// TODO: put canvasParent in the scene