当前位置: 首页 > 知识库问答 >
问题:

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

卫逸春
2023-03-14

我试图强制 GridPane 的子项适合它所在的单元格的大小。在本例中,我将创建一个月视图日历,无论其中的内容如何,列和行都是一个设置的大小。

在这个日历上,每个单元格包含一个普通的< code>VBox,每个< code>VBox包含一个标签,显示一个月中的某一天以及当天的每个事件。许多日子没有事件;有些只有一个事件;少数有一个以上的事件。

日历大小取决于窗口大小,并将根据窗口进行增大和缩小。现在,如果单元格太小而无法容纳所有事件,则单元格中当天的一个 VBox 的高度将大于单元格。

标题行具有以下约束:

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.

共有1个答案

左翰海
2023-03-14

正如@fabian正确提到的,< code>VBox的大小完全取决于其子元素的大小。如果您希望有一个不依赖其子容器调整大小的容器,您可以使用< code>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);

请注意,尽管形状突出到了< code>c0的边界之外,但< code>c0的边界保持不变,这表明其大小不受影响。为了防止内容突出,您需要添加一个剪辑:

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

如果你想要一个更花哨的剪辑,而不是一个简单的修剪,如淡入,淡出和阴影,你可以在这里阅读这个非常好的教程。

现在,只需将此圆圈替换为您的VBox,使VBox</code>成为此“窗格</code>”的子项,然后将窗格</code>添加到您的网格窗格</code>。我将在这里提供我的最终代码作为参考:

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

二者择一地...

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

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

 类似资料:
  • 我有一个学校项目或类似的东西,我试图为用户制作一个注册面板。当用户点击注册时,这个面板会打开。它看起来像这样。 我想做的是禁用创建按钮,只有在对话框上有3个检查时才会启用。 我在对话框上使用GridPane,我在考虑返回这些单元格上的某些节点(检查是图像视图),并检查条件是否为真。然而,我不知道如何从GridPane返回节点。如果你有其他方法来解决这个问题,也没关系。 这是代码的相关部分。

  • 我正在用JavaFX写一个程序 硼烷- 我希望能够添加尽可能多的行到gridpane,并让scrollpane自动扩展自己。 注意:我有一些很长的文件,所以我只包括重要的部分。如果您需要整个FXML或Controller文件,请给我留言。 以下是我的gridpane/scrollpane的FXML: 我有以下代码在我的控制器内的FXML 谢谢大家的帮助! 瑞恩

  • 有人知道如何成功编程这个简单的属性吗?占据整个窗口的网格窗格?我错过了什么? 谢谢LD

  • 我正在编写一个JavaFX程序,制作一个随机颜色的网格。当调整窗口大小时,网格应该调整到尽可能大,同时仍然保持正方形,并在底部为文本留出空间。 一切工作正常,但我遇到的问题是,当调整GridPane的大小时,它会留下一些空隙。调整窗口大小时,间隙的大小会略有变化。有人能帮我找出如何消除这些差距吗?我包括完整的代码。它不太长。谢谢你。

  • 我把网格窗格设置得很好。但如何在每个单元格中放置事件处理程序?就像鼠标双击和右键单击一样。谁能给我举个例子吗?非常感谢。

  • 如何使用< code>GridPane上的权重设置行/列大小? 例如,如果我想要五行,其中三行是未知的固定大小,一行占用剩余空间的三分之一,另一行占用剩余空间的三分之二(见下图),我该如何实现呢? 我查看了使用,其中两个有但这只允许平均共享剩余空间。 我尝试使用百分比,因为我在文档< code >中看到,如果widthPercent(或heightPercent)值的总和大于100,这些值将被视为