如何将侦听器添加到使用CheckBoxListCell的列表视图中的复选框

我有一个listview,它使用CheckBoxListCell显示一个列表,其中包含项目旁边的复选框。 如何向此复选框添加侦听器以了解项目何时被选中或未被选中? 在此处输入图像描述

您没有向复选框添加侦听器。 您将一个侦听器添加到对象的observable属性,该属性与CheckBoxListCell.forListView例程的复选框关联。

建立关联:

 ListView checklist = new ListView<>(tasks); checklist.setCellFactory(CheckBoxListCell.forListView(Task::selectedProperty)); 

为所有项添加侦听器:

 tasks.forEach(task -> task.selectedProperty().addListener((observable, wasSelected, isSelected) -> { if (isSelected) { // . . . } else { // . . . } })); 

文档

这个过程在CheckBoxListCell.forListView javadoc中描述如下:

getSelectedProperty – 一个回调,给定一个T类型的对象(从ListView.items列表中取出一个值),将返回一个ObservableValue,表示是否选择了给定的项目。 此ObservableValue将双向绑定(意味着单元格中的CheckBox将根据用户交互设置/取消设置此属性,并且CheckBox将反映ObservableValue的状态,如果它在外部更改)。

示例程序

一个示例程序,演示了一些可以与CheckBoxListCell一起使用的模式:

 import javafx.application.Application; import javafx.beans.property.*; import javafx.collections.*; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.ListView; import javafx.scene.control.cell.CheckBoxListCell; import javafx.scene.layout.HBox; import javafx.stage.Stage; import javafx.util.StringConverter; import java.util.*; import java.util.stream.Collectors; public class CheckList extends Application { @Override public void start(Stage stage) throws Exception{ ObservableList tasks = FXCollections.observableArrayList( Arrays.stream(taskNames).map(Task::new).collect(Collectors.toList()) ); ListView reactionLog = new ListView<>(); tasks.forEach(task -> task.selectedProperty().addListener((observable, wasSelected, isSelected) -> { if (isSelected) { reactionLog.getItems().add(reactionStrings.get(task.getName())); reactionLog.scrollTo(reactionLog.getItems().size() - 1); } })); ListView checklist = new ListView<>(tasks); checklist.setCellFactory(CheckBoxListCell.forListView(Task::selectedProperty, new StringConverter() { @Override public String toString(Task object) { return object.getName(); } @Override public Task fromString(String string) { return null; } })); HBox layout = new HBox(10, checklist, reactionLog); layout.setPrefSize(350, 150); layout.setPadding(new Insets(10)); Scene scene = new Scene(layout); stage.setScene(scene); stage.show(); } public static class Task { private ReadOnlyStringWrapper name = new ReadOnlyStringWrapper(); private BooleanProperty selected = new SimpleBooleanProperty(false); public Task(String name) { this.name.set(name); } public String getName() { return name.get(); } public ReadOnlyStringProperty nameProperty() { return name.getReadOnlyProperty(); } public BooleanProperty selectedProperty() { return selected; } public boolean isSelected() { return selected.get(); } public void setSelected(boolean selected) { this.selected.set(selected); } } public static void main(String[] args) { launch(args); } private static final String[] taskNames = { "Walk the dog", "Skin the cat", "Feed the pig" }; private static final Map reactionStrings = new HashMap<>(); static { reactionStrings.put("Walk the dog", "The dog thanks you"); reactionStrings.put("Skin the cat", "The cat hates you"); reactionStrings.put("Feed the pig", "The pig wants more"); } } 

选择第一项一次和第三项三次后输出样品。

小猪

如果项目尚未具有指示是否已选择的属性,则可以使用以下选项:

 public class CheckedListViewCheckObserver extends SimpleObjectProperty> { BooleanProperty getObserverForObject(T object) { BooleanProperty value = new SimpleBooleanProperty(false); value.addListener((observable, oldValue, newValue) -> { CheckedListViewCheckObserver.this.set(new Pair<>(object, newValue)); }); return value; } } 

然后使用它,你只需:

 CheckedListViewCheckObserver observer = new CheckedListViewCheckObserver<>(); checklist.setCellFactory(CheckBoxListCell.forListView(observer::getObserverForObject)); 

现在,您可以设置侦听器以侦听任何更改:

 observer.addListener((obs, old, curr) -> { if (curr.getValue()) { System.out.println("You have checked " + curr.getKey()); } else { System.out.println("You have unchecked " + curr.getKey()); } }); 

这种方法的优点是它不依赖于所使用的对象; 相反,因为它是通用的,你可以简单地将它附加到已经存在的列表视图,它开始工作。

希望这有助于某人。