2015-11-15 44 views
1

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

下面是一个简单的例子,它显示了这种行为:

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

正在被在TableView这样设置:

TableView<ObservableList<MyData>> table = new TableView<>(); 
table.setSelectionModel(new MySelectionModel(table)); 
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 

我已经证实,新指数是正确的通过在两个支持ObservableLists上添加ListChangeListeners并显示Changes来设置。输出是我期望的,例如

选定的单元格{[TablePosition [行:8,柱:空,的tableView:TableView中@ 11924c25 [的styleClass =表视图]]]由[TablePosition [行替换:12,柱:空,的tableView:TableView中@ 11924c25 [的styleClass =表视图]]]在0}

所选项目{[[MyCustomTableView $细胞@ 1c988ebb,MyCustomTableView $细胞@ 6b80b2be]]由[[MyCustomTableView $细胞@ 4a17d76d,MyCustomTableView $细胞替换@ 6e48d6d] at 0}

是否有任何我丢失的,这将需要TableView更新其选择时, TableViewSelectionModel更改选择?

+0

您是在执行'getSelectedIndices()',还是在选择更改时修改该列表? –

+0

@James_D我没去过,但我已经加入了,它仍然显示同样的问题。 – resueman

+0

可能需要[MCVE]。 (我知道用'TableViewSelectionModel'实现很难做到最小化。) –

回答

1

看来你需要重写,除了你已经拥有的那些方法,是

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

不是你也有一个错误。 Collections.singleton(...)返回一个不可修改的列表,所以如果您选择一行,然后尝试添加项目到选择,您会得到一个UnsupportedOperationException。您的clearAndSelect需要实现为

public void clearAndSelect(int row, TableColumn<S, ?> tableColumn){ 
    selection.clear(); 
    selection.add(row); 
    updateSelection(); 
} 
+0

不知何故,这适用于我在此发布的示例,但不适用于我的实际代码:P。但现在应该很容易解决,我有一个工作示例。感谢您的解决方案。 – resueman