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

时间:2014-08-17 07:59:32

标签: java listview javafx

我有一个列表视图,它使用CheckBoxListCell来显示列表,其中包含项目旁边的复选框。如何向此复选框添加侦听器以了解项目何时被选中或未被选中? enter image description here

2 个答案:

答案 0 :(得分:12)

<强>解决方案

您没有在复选框中添加监听器。您可以向对象的observable属性添加一个侦听器,该属性与CheckBoxListCell.forListView例程的复选框相关联。

设置关联:

ListView<Task> 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<Task> tasks = FXCollections.observableArrayList(
                Arrays.stream(taskNames).map(Task::new).collect(Collectors.toList())
        );

        ListView<String> 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<Task> checklist = new ListView<>(tasks);
        checklist.setCellFactory(CheckBoxListCell.forListView(Task::selectedProperty, new StringConverter<Task>() {
            @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<String, String> 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");
    }
}

选择第一个项目一次,第三个项目选择三次后输出示例。

piggy

答案 1 :(得分:0)

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

public class CheckedListViewCheckObserver<T> extends SimpleObjectProperty<Pair<T, Boolean>> {

    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());
    }
});

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

希望这有助于某人。