gpt4 book ai didi

JavaFX - 强制 GridPane 的 child 适应单元格的大小

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:22:48 25 4
gpt4 key购买 nike

我试图强制 GridPane 的子项适应它所在的单元格的大小。在这种情况下,我正在创建一个月 View 日历,列和行是一组大小而不管里面是什么。

在这个日历上,每个单元格都包含一个普通的 VBox,每个 VBox 都包含一个标签,该标签显示该月的某天以及该天的每个事件。许多日子没有事件;他们中的一些人只举办一场 Activity ;少数有不止一个事件。

日历大小取决于窗口大小,并会根据窗口大小增长和缩小。现在,如果单元格太小而无法容纳所有事件,那么单元格中那天的那个 VBox 的高度会变得比单元格大。

enter image description here

标题行具有以下约束:

HEADER_CONSTRAINT = new RowConstraints(10, -1, 500, 
Priority.NEVER, VPos.BASELINE, true);

其他行有这个约束:

ROW_CONSTRAINT = new RowConstraints(30, 30, Integer.MAX_VALUE,
Priority.ALWAYS, VPos.TOP, true);

我认为我需要做的是:

grid.add(cell, c, r);
vbox.maxHeightProperty().bind(grid.getRow(r).heightProperty()); // <-- this line is not right, but something like this.

最佳答案

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

ss1

添加一个形状来测试:

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

ss2

请注意,虽然形状突出到 c0 的边界之外,但 c0 的边界保持不变,表明其大小不受影响。为了防止内容突出,需要加一个夹子:

c0.setClip(new Rectangle(c0.getPrefWidth(), c0.getPrefHeight()));

ss3

如果你想要更花哨的剪辑而不是简单的修剪,例如淡入、淡出和阴影,你可以阅读这个非常好的教程 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 的大小发生变化时动态调整单元格的大小,您可以向其 widthPropertyheightProperty 添加一个监听器像这样:

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

或者……

如果您希望使用 ColumnConstraintsRowConstraints 来确定单元格大小,您可以将 Pane 设置为展开,并且只更新它们的监听器中的剪辑,现在监听 ColumnConstraintsRowConstraints:

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

关于JavaFX - 强制 GridPane 的 child 适应单元格的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51275545/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com