JavaFXTableView列复选框侦听器

JavaFXTableView列复选框侦听器,javafx,Javafx,我有一个带有复选框的表格列。我必须做这个监听器,我想知道为什么每次点击后监听器都会加倍 selectedColumn.setCellFactory(column -> new CheckBoxTableCell<>()); selectedColumn.setCellValueFactory(cellData -> { Dir dir = cellData.getValue(); BooleanProperty proper

我有一个带有复选框的表格列。我必须做这个监听器,我想知道为什么每次点击后监听器都会加倍

    selectedColumn.setCellFactory(column -> new CheckBoxTableCell<>());
    selectedColumn.setCellValueFactory(cellData -> {
        Dir dir = cellData.getValue();
        BooleanProperty property = dir.isSelectedProperty();

        property.addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) ->{
            System.out.println(newValue);
        });

        return property;
    });
selectedColumn.setCellFactory(column->new CheckBoxTableCell());
selectedColumn.setCellValueFactory(cellData->{
Dir=cellData.getValue();
BooleanProperty=dir.isSelectedProperty();

addListener((ObservalEvalue发生这种情况是因为
TableView
(和
ListView
等)等控件将其内容虚拟化。从TableView Javadoc:

TableView控件设计为可视化无限数量的 数据行,分为列

TableView
可能包含大量项目。但是,在屏幕上,您可能会在任何时间点看到10-30行(每行对应一个项目)

如果没有虚拟化,如果您有100万个项目,它将创建100万个
TableRow
对象(我们没有提到
TableCell
),每个
TableRow
维护所有状态/值。这需要大量内存和处理能力

另一方面,通过虚拟化,如果您的视图只能显示10行,
TableView
将仅创建12个
TableRow
实例。当您滚动列表时,一些项目从您的视线中消失。这些
TableRow
实例将立即重新用于进入您视线的项目

这就是为什么
setCellFactory()
setCellValueFactory()
方法属于
Callback
类型的原因。每次重用一行时,它都会调用此回调对象来更新
TableCell
。这就是反复添加侦听器的原因,从而导致此问题

根据需要,可以向项目列表中添加
ListChangedListener

ObservableList<Dir> list = FXCollections.observableArrayList(item -> new javafx.beans.Observable[] {item.isSelectedProperty()});
list.addAll(DirList.getDirList());
dirList.setItems(list);

list.addListener(new ListChangeListener<Dir>() {
    @Override public void onChanged(javafx.collections.ListChangeListener.Change<? extends Dir> c) {
        while (c.next()) {
            if (c.wasUpdated()) {
                // Do something
            }
        }
    }
});
observeList=FXCollections.observearraylist(item->newjavafx.beans.observeable[]{item.isSelectedProperty()});
addAll(DirList.getDirList());
dirList.setItems(列表);
addListener(新的ListChangeListener(){

@Override public void onChanged(javafx.collections.ListChangeListener.Change我看到您有一个名为
Dir
的模型,其中选择了
BooleanProperty
名为

您只需让
cellValueFactory
只需:

selectedColumn.setCellValueFactory(cellData->cellData.getValue().isSelectedProperty());

如果选中/取消选中表格单元格中的
复选框,这将更新模型的属性

如果您使用复选框的这个选中/取消选中状态,您可以使用模型,并在那里添加侦听器,您将得到相同的结果。然后只添加一次侦听器

您应该创建
Dir
的实例,然后您可以在
初始化中执行以下操作:

dir1.selectedProperty().addListener((observable, oldValue, newValue) -> {
            dir2.selectedProperty().set(oldValue);
        });
或者任何您想要的,那么您确定只添加了一次侦听器。
正如@Jai所提到的,单元格数据被多次使用,每次调用
回调
时,侦听器都被添加到属性中,因此如果您想避免多次将侦听器添加到属性中,请不要在该方法中使用它。

这段代码至少驻留在哪里?至少显示整个方法。请阅读并执行accor在初始化中method@Light你为什么要这样做?这不是倾听它变化的正确方式。@Sunflame,有很多方法,我认为这一个如果有效的话是正确的。不完全正确,但是你的建议也不起作用。很抱歉,你没有提供任何新的内容。你只是写了一篇不好的文章,就这样。