JavaFX Gridpane 上的粘性 Headers

Sticky Headers on JavaFX Gridpane

我想知道是否有可能在 JavaFX 中的 GridPane 上实现 Sticky Headers,这意味着 GridPane 的一行保留在原位,而您可以滚动浏览窗格的其余行。

可以,但您需要确保 header 节点是 GridPane.children 列表的最后一个 children。这允许您将 header 节点的 translateY 属性 设置为保留在 ScrollPane 的顶部,包裹 GridPane:

GridPane grid = new GridPane();

// fill grid
Color[] colors = new Color[]{Color.RED, Color.ORANGE, Color.LIGHTGREEN, Color.LIGHTBLUE};
for (int i = 1; i <= 100; i++) {
    grid.add(new Rectangle(50, 50, colors[(2 * i - 2) % colors.length]), 0, i);
    grid.add(new Label(Integer.toString(2 * i - 1)), 0, i);
    grid.add(new Rectangle(50, 50, colors[(2 * i - 1) % colors.length]), 1, i);
    grid.add(new Label(Integer.toString(2 * i)), 1, i);
}

// create & add header
Node[] headers = new Node[] {
    createHeaderNode("H1"),
    createHeaderNode("H2")
};
grid.addRow(0, headers);

ScrollPane scrollPane = new ScrollPane(grid);
scrollPane.setPrefHeight(400);

// keep header in position on top of the viewport
InvalidationListener headerUpdater = o -> {
    final double ty = (grid.getHeight() - scrollPane.getViewportBounds().getHeight()) * scrollPane.getVvalue();
    for (Node header : headers) {
        header.setTranslateY(ty);
    }
};
grid.heightProperty().addListener(headerUpdater);
scrollPane.viewportBoundsProperty().addListener(headerUpdater);
scrollPane.vvalueProperty().addListener(headerUpdater);
private static Label createHeaderNode(String text) {
    Label label = new Label(text);
    label.setMaxWidth(Double.MAX_VALUE);
    label.setStyle("-fx-border-style: solid; -fx-background-color: white;");
    return label;
}