Java 自定义TableViewSelectionModel未更新

Java 自定义TableViewSelectionModel未更新,java,javafx,selectionmodel,Java,Javafx,Selectionmodel,我正试图在JavaFX中编写一个与我的应用程序一起使用的自定义程序。我已经实现了所有的抽象方法,并且正在更新选定的项目和选定的单元格列表。但是,当我单击另一行时,表中显示的实际选择不会改变 下面是一个简化的示例,显示了此行为: import java.util.*; import javafx.scene.control.*; import javafx.scene.control.TableView.TableViewSelectionModel; import javafx.collecti

我正试图在JavaFX中编写一个与我的应用程序一起使用的自定义程序。我已经实现了所有的抽象方法,并且正在更新选定的项目和选定的单元格列表。但是,当我单击另一行时,表中显示的实际选择不会改变

下面是一个简化的示例,显示了此行为:

import java.util.*;
import javafx.scene.control.*;
import javafx.scene.control.TableView.TableViewSelectionModel;
import javafx.collections.*;
import javafx.beans.property.ReadOnlyListWrapper;

public class MySelectionModel<S> extends TableViewSelectionModel<S>{
    Set<Integer> selection = new HashSet<>();
    final ObservableList<TablePosition<S, ?>> selectedCells = FXCollections.<TablePosition<S, ?>>observableArrayList();
    final ObservableList<S> selectedItems = FXCollections.<S>observableArrayList();
    final ObservableList<Integer> selectedIndices = FXCollections.<Integer>observableArrayList();

    public MySelectionModel(TableView<S> tableview){
        super(tableview);
        setCellSelectionEnabled(false);
    }
    public ObservableList<S> getSelectedItems(){
        return new ReadOnlyListWrapper<S>(selectedItems);
    }
    public void clearSelection(int row, TableColumn<S, ?> tableColumn){
        selection.remove(Integer.valueOf(row));
        updateSelection();
    }
    public void clearAndSelect(int row, TableColumn<S, ?> tableColumn){
        selection = Collections.singleton(row);
        updateSelection();
    }
    public void select(int row, TableColumn<S, ?> tableColumn){
        selection.add(Integer.valueOf(row));
        updateSelection();
    }
    public boolean isSelected(int row, TableColumn<S, ?> tableColumn){
        return selection.contains(Integer.valueOf(row));
    }
    public ObservableList<TablePosition> getSelectedCells(){
        return new ReadOnlyListWrapper<TablePosition>((ObservableList<TablePosition>)(Object)selectedCells);
    }
    public ObservableList<Integer> getSelectedIndices(){
        return new ReadOnlyListWrapper<Integer>(selectedIndices);
    }
    public void selectBelowCell(){}
    public void selectAboveCell(){}
    public void selectRightCell(){}
    public void selectLeftCell(){}
    public void updateSelection(){
        List<TablePosition<S, ?>> positions = new ArrayList<>();
        List<S> items = new ArrayList<>();
        List<Integer> indices = new ArrayList<>();
        TableView<S> tableView = getTableView();
        for(Integer i : selection){
            positions.add(new TablePosition<S, Object>(tableView, i.intValue(), null));
            items.add(getTableView().getItems().get(i.intValue()));
            indices.add(i);
        }
        selectedCells.setAll(positions);
        selectedItems.setAll(items);
        selectedIndices.setAll(indices);
    }
}
我已经通过在两个备份
observateList
s上添加
ListChangeListener
s并显示
Change
s来确认新索引的设置是正确的。输出是我所期望的,例如

所选单元格{[TablePosition[行:8,列:null,tableView:TableView@11924c25[styleClass=表格视图]]]替换为[TablePosition[行:12,列:null,表格视图:TableView@11924c25[styleClass=表视图]]]位于0}

所选项目{[[MyCustomTableView]$Cell@1c988ebb,MyCustomTableView$Cell@6b80b2be]]替换为[[MyCustomTableView]$Cell@4a17d76d,MyCustomTableView$Cell@6e48d6d]]在0}


TableViewSelectionModel
更改其选择时,
TableView
更新其选择是否需要我缺少任何东西?

除了您已有的方法之外,您需要覆盖的方法似乎是

public void select(int row) ;
通过委托给现有的
select
方法,您可以轻松实现:

@Override
public void select(int row) {
    select(row, null);
}
我还建议覆盖以下内容:

@Override
public void clearAndSelect(int row) {
    clearAndSelect(row, null);
}

@Override
public void selectRange(int start, int end) {
    IntStream.range(start, end).forEach(selection::add);
    updateSelection();
}

@Override
public boolean isSelected(int row) {
    return isSelected(row, null);
}
请注意,您还有一个bug
Collections.singleton(…)
返回一个不可修改的列表,因此如果您选择一行,然后尝试向选择中添加项目,则会得到一个
UnsupportedOperationException
。您的
clearAndSelect
需要按如下方式实现

public void clearAndSelect(int row, TableColumn<S, ?> tableColumn){
    selection.clear();
    selection.add(row);
    updateSelection();
}
public void clearAndSelect(int行,TableColumn表列){
selection.clear();
选择。添加(行);
更新选择();
}

您是在实现
GetSelectedDices()
,还是在选择发生变化时修改该列表?@James\u D我没有,但我已经添加了它,但它仍然显示出相同的问题。可能需要一个解决方案。(我知道用
TableViewSelectionModel
实现很难最小化。)@James\u我希望这不是必要的。太多的方法让它变得简短:P我添加了最短的可复制版本。不知何故,这对我在这里发布的示例有效,但对我的实际代码无效:P。但是现在我有了一个工作示例,应该很容易修复它。谢谢你的解决方案。
public void clearAndSelect(int row, TableColumn<S, ?> tableColumn){
    selection.clear();
    selection.add(row);
    updateSelection();
}