在我的 TableView 中,我想要一个包含复选框的列。通过此复选框,用户可以选择要为特定操作(例如删除)标记哪些行。我尝试过使用 CheckBoxTableCell,但我看到的所有示例都已将复选框的值绑定(bind)到模型的某些 boolean 属性。我的TableView所基于的模型是JPA实体,并且没有这样的字段。我也不愿意添加这样的字段,因为除了用于此行选择目的之外,它与模型无关。
因此我的问题是,是否可以使用 CheckBoxTableCell 来选择多行。如果是这样,我该如何实现它并随后获取所选的每一行?如果没有,使用表列中的复选框实现多重选择的最佳方法是什么?
谢谢。
最佳答案
首先请注意,您只需使用 TableView 的默认选择实现即可实现此功能。 IE。调用table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
。然后用户可以选择多行,您可以只对选定的行进行操作。
如果您想使用复选框列来实现此功能,这并不太困难:
CheckBoxTableCell
有一个 selectedStateCallback
属性,这是一个将单元格索引(即其行)映射到 ObservableValue<Boolean>
的函数。 。复选框的选定状态将绑定(bind)(如果可观察 boolean 值可写,则双向)到作为此函数结果的可观察 boolean 值的状态。
因此,正如您所见,通常您会将其映射到 BooleanProperty
在模型对象中,但您可以将其映射到您喜欢的任何属性。如果您没有,您可以专门为此目的创建一个。
例如,您可能想要维护当前所选项目的某种集合:例如您可以使用 ObservableSet
。 (在下面的示例中,我假设表中没有重复的项目,即 .equals(...)
。如果您的表可能包含重复的行,则需要做更多的工作。)然后您只需将监听器注册到确保:
- 如果表示复选框选定状态的属性发生更改,您将更新选定项目的可观察集
- 如果可观察的所选项目集发生更改,您可以更新复选框(通过更新 boolean 属性)
- 如果重复使用该单元格来表示不同的项目,则需要更新该复选框。您可以使用单元格的
itemProperty
注册监听器为此目的。
这是一个示例,使用一个仅显示字符串的非常简单的表格。因为我们要从单元格的getItem
中获取整行所代表的项方法中,我们使列的类型与表的类型相同(本例中为 String
,因此我们有 TableColumn<String, String>
),并使用 cellValueFactory
包装整行的对象:selectedCol.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue()));
。在现实生活中,您的表类型可能会更复杂,并且可能会使用 ReadOnlyObjectWrapper<>(cellData.getValue());
。
import java.util.HashSet;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import javafx.collections.SetChangeListener.Change;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class TableViewSelectByCheckBox extends Application {
@Override
public void start(Stage primaryStage) {
TableView<String> table = createTable();
TableColumn<String, String> selectedCol = new TableColumn<>();
selectedCol.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue()));
ObservableSet<String> selectedItems = FXCollections.observableSet(new HashSet<>());
selectedCol.setCellFactory(col -> {
// boolean property represents if the check box in the cell is selected:
BooleanProperty selected = new SimpleBooleanProperty();
// create check box cell and bind its state to property:
CheckBoxTableCell<String, String> cell = new CheckBoxTableCell<>(index -> selected);
// update set of selected indices if checkbox state changes:
selected.addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
selectedItems.add(cell.getItem());
} else {
selectedItems.remove(cell.getItem());
}
});
// update check box state if set of selected indices changes:
selectedItems.addListener((Change<? extends String> change) -> {
selected.set(cell.getItem() != null && selectedItems.contains(cell.getItem()));
});
// update check box when cell is reused for a different index:
cell.itemProperty().addListener((obs, oldItem, newItem) -> {
selected.set(newItem != null && selectedItems.contains(newItem));
});
return cell ;
});
table.getColumns().add(0, selectedCol);
Button button = new Button("Show selected");
button.setOnAction(e -> selectedItems.forEach(System.out::println));
BorderPane.setAlignment(button, Pos.CENTER);
BorderPane.setMargin(button, new Insets(5));
BorderPane root = new BorderPane(table, null, null, button, null);
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private TableView<String> createTable() {
TableView<String> table = new TableView<>();
table.setEditable(true);
TableColumn<String, String> itemCol = new TableColumn<>("Item");
itemCol.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue()));
table.getColumns().add(itemCol);
for (int item = 1 ; item <= 100; item++) {
table.getItems().add("Item "+item);
}
return table ;
}
public static void main(String[] args) {
launch(args);
}
}
关于java - 我可以在 TableView 中使用 CheckBoxTableCell 作为让用户选择多行的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34940563/