正如@fabian 正确提到的,VBox 的大小完全取决于其子项的大小。如果您希望拥有一个不根据其子级调整大小的容器,您可以使用 Pane 代替。像这样:
public void start(Stage primaryStage)
{
GridPane root = new GridPane();
Scene scene = new Scene(root, 300, 300);
int c = 0, r = 0;
Pane c0 = new Pane();
c0.setPrefSize(200, 200);
c0.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
new BorderWidths(1))));
root.add(c0, c, r);
primaryStage.setScene(scene);
primaryStage.show();
}
添加要测试的形状:
Pane c0 = new Pane();
c0.setPrefSize(200, 200);
c0.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
new BorderWidths(1))));
{
Circle circle = new Circle(160, Color.BLUE);
circle.setCenterX(160);
circle.setCenterY(160);
c0.getChildren().add(circle);
}
root.add(c0, c, r);
请注意,虽然形状突出到c0 的边界之外,但c0 的边界保持不变,表明它的大小不受影响。为防止内容突出,需要添加剪辑:
c0.setClip(new Rectangle(c0.getPrefWidth(), c0.getPrefHeight()));
如果您想要更花哨的剪辑而不是简单的修剪,例如淡入、淡出和阴影,您可以阅读这个非常好的教程here。
现在只需将这个Circle 替换为您的VBox,这样VBox 就是这个Pane 的一个子代,然后将Pane 添加到您的GridPane 中就完成了。我将在这里提供我的最终代码作为参考:
public void start(Stage primaryStage)
{
GridPane root = new GridPane();
Scene scene = new Scene(root, 300, 300);
int c = 0, r = 0;
Pane c0 = new Pane();
c0.setPrefSize(200, 200);
c0.setClip(new Rectangle(c0.getPrefWidth(), c0.getPrefHeight()));
c0.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
new BorderWidths(1))));
{
Circle circle = new Circle(160, Color.BLUE);
circle.setCenterX(160);
circle.setCenterY(160);
c0.getChildren().add(circle);
}
root.add(c0, c, r);
primaryStage.setScene(scene);
primaryStage.show();
}
更新:
@Jai 指出在这个实现中大小是静态的。如果您希望在GridPane 的大小发生变化时动态调整单元格的大小,您可以向其widthProperty 和heightProperty 添加一个侦听器,如下所示:
int rowCount = 5, columnCount = 7; // You should know these values.
ChangeListener<Number> updater = (o, oV, nV) ->
{
double newWidth = root.getWidth() / columnCount;
double newHeight = root.getHeight() / rowCount;
root.getChildren().forEach(n ->
{
// Assuming every child is a Pane.
Pane p = (Pane) n;
p.setPrefSize(newWidth, newHeight);
p.setClip(new Rectangle(newWidth, newHeight));
});
};
root.widthProperty().addListener(updater);
root.heightProperty().addListener(updater);
或者...
如果您希望使用ColumnConstraints 和RowConstraints 来确定单元格大小,您可以将Panes 设置为展开,并且仅在侦听器中更新它们的剪辑,现在侦听器将侦听ColumnConstraints 和@987654347 @:
ColumnConstraints cc = new ColumnConstraints(200);
RowConstraints rc = new RowConstraints(200);
c0.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE);
c0.setClip(new Rectangle(cc.getPrefWidth(), rc.getPrefHeight()));
还有……
ChangeListener<Number> updater = (o, oV, nV) ->
{
root.getChildren().forEach(n ->
{
// Assuming every child is a Pane.
Pane p = (Pane) n;
p.setClip(new Rectangle(cc.getPrefWidth(), rc.getPrefHeight()));
});
};
cc.prefWidthProperty().addListener(updater);
rc.prefHeightProperty().addListener(updater);