JavaFX-强制GridPane的子代适合单元格的大小

时间:2018-07-11 00:17:53

标签: java javafx

我试图强制GridPane的子项适合其所在单元格的大小。在这种情况下,我正在创建一个月视图日历,并且列和行都是设置的大小,而与里边啥啊。

在此日历上,每个单元格包含一个普通的VBox,每个VBox包含一个标签,该标签显示该月的某天以及该天的每个事件。许多日子里没有活动。其中一些有一个事件;还有一些有多个活动。

日历大小取决于窗口大小,并且会根据窗口大小而增加和缩小。现在,如果该单元格太小而无法容纳所有事件,则该单元格中那天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.

1 个答案:

答案 0 :(得分:0)

正如@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添加到您的{ {1}},您就完成了。我将在此处提供我的最终代码作为参考:

GridPane

更新

@Jai指出,此实现中的大小是静态的。如果您希望在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(); } 的大小发生变化的情况下动态调整单元格的大小,可以向其GridPanewidthProperty添加一个侦听器,如下所示:

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设置为展开,并仅在监听器中更新其片段,该监听器现在可以监听PaneColumnConstraints

RowConstraints

和...

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