JavaFX Gridpane上的粘滞标题

时间:2018-05-07 13:33:00

标签: javafx-8 sticky gridpane

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

1 个答案:

答案 0 :(得分:1)

这是可能的,但您需要确保标头节点是GridPane.children列表的最后一个子节点。这允许您将标题节点的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;
}