2015-11-15 45 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