繁体   English   中英

JavaFX TableView单击标题

[英]JavaFX TableView Click on Header

有没有一种方法可以在表的标题上单击鼠标?

为什么我需要这个?

我有一个包含许多列的表。 但是对于整个表来说,只有一个特定的智慧。 为了避免滚动,我想给每个列指定一个特定的宽度(大约50),并且,即使您单击标题,此列也会展开,以便您可以阅读内容。 如果单击另一个标题,则前一个标题将折叠。

希望有人可以帮助我:)

不幸的是,没有一个很好的方法来做到这一点。 唯一的公共API选项是用您自己的标签替换该列的“图形”,然后向其添加鼠标侦听器。 为此,您还需要清除所有现有的列文本。

请注意,默认情况下,列具有单击侦听器来实现排序,似乎您不希望这种行为,因此还需要调用column.setSortable(false)

@Override
public void start(Stage primaryStage) throws Exception {
    TableView<String> tableView = new TableView<>();
    TableColumn<String, Object> x = new TableColumn<>("x");
    tableView.getColumns().add(x);
    TableColumn<String, Object> y = new TableColumn<>("");
    tableView.getColumns().add(y);

    x.setSortable(false);
    y.setSortable(false);

    makeHeader(x, "X", 0);
    makeHeader(y, "Y", 1);

    EventHandler<? super MouseEvent> handler = event -> {
        System.out.println("Column clicked " + ((Node)event.getTarget()).getProperties().get("index"));
    };
    x.getGraphic().addEventFilter(MouseEvent.MOUSE_CLICKED, handler);
    y.getGraphic().addEventFilter(MouseEvent.MOUSE_CLICKED, handler);
    primaryStage.setScene(new Scene(tableView));
    primaryStage.show();
}

private void makeHeader(TableColumn<?, ?> target, String name, int index) {
    VBox vBox = new VBox(new Label(name));
    vBox.setAlignment(Pos.CENTER);
    vBox.getProperties().put("index", index);
    target.setGraphic(vBox);
    target.setText("");
}
// Step 0: call setOnShown(...).
stage.setOnShown(event -> {
  setHeaderClickListeners(); // Call this method  when the stage is shown.
});

然后创建方法setHeaderClickListeners() ,如下所示:

private void setHeaderClickListeners() {
  // Step 1: Get the table header row.
  TableHeaderRow headerRow = null;
  for (Node n : ((TableViewSkin<?>) tableView.getSkin()).getChildren()) {
    if (n instanceof TableHeaderRow) {
      headerRow = (TableHeaderRow) n;
    }
  }
  if (headerRow == null) {
    return;
  }

  // Step 2: Get the list of the header columns.
  NestedTableColumnHeader ntch = (NestedTableColumnHeader) headerRow.getChildren().get(1);
  ObservableList<TableColumnHeader> headers = ntch.getColumnHeaders();

  // Step 3: Add click listener to the header columns.
  for (int i = 0; i < headers.size(); i++) {
    TableColumnHeader header = headers.get(i);
    final int index = i;
    header.setOnMouseClicked(mouseEvent -> {

      // Optional:
      // Get the TableColumnBase (which is the object responsible
      // for displaying the content of the column.)
      TableColumnBase column = header.getTableColumn();

      // Step 4: Handle double mouse click event.
      if (mouseEvent.getButton() == MouseButton.PRIMARY && mouseEvent.getClickCount() == 2) {
        P.x("Header cell " + index + " clicked! " + column.getText());
      }
    });
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM