如果使用不同列选择多行,则SelectedItem为空

时间:2015-06-15 12:18:47

标签: java javafx java-8 javafx-8

TableView中有SelectionMode.MULTIPLE。使用ListChangeListener我可以捕捉多行的选择(按 Shift )。

但是,只有在没有列的区域中的同一列 OR 中选择了项目时,我的解决方案才有效。用4个例子说明的Gif:

  1. 确定:在州列中使用 Shift 选择3个项目
  2. 确定:在Idx列中使用 Shift 选择4个项目
  3. 确定:使用 Shift 从州列开始选择4个项目到不带列的区域
  4. 错误:尝试使用 Shift 从State列开始选择4个项目到Data Item列
  5. Selection of multiple items in different columns

    问题似乎是SelectedItems - 列表在上一个例子中显然是空的。我真的很感谢你对这个问题的帮助。

    这是我的方法:

    ObservableList<DataRowModel> dataRows = FXCollections.observableArrayList();
    dataRows.addAll(dataSetModel.getRows());
    tableDataRow.setItems(dataRows);
    tableDataRowStateColumn.setCellValueFactory(f -> f.getValue().getState());
    
    tableDataRow.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
    tableDataRow.getSelectionModel().getSelectedItems()
    .addListener((ListChangeListener.Change<? extends DataRowModel> c) -> {
        while (c.next()) {
            c.getRemoved().stream().forEach(remitem -> remitem.setSelected(false));
            c.getAddedSubList().stream().forEach(additem -> additem.setSelected(true));
            System.out.println(c.getList()); //Empty [] when selected using different columns
        }
    });
    

    为了更好地理解我的代码:setSelected(...)在我的BooleanProperty上设置DataRowModel,该import javafx.application.Application; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.SelectionMode; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.stage.Stage; public class TableViewSample extends Application { private TableView<DataRowModel> tableDataRow = new TableView<DataRowModel>(); private TableColumn<DataRowModel, String> tableDataRowNameColumn = new TableColumn<>("Data Item"); private TableColumn<DataRowModel, String> tableDataRowStateColumn = new TableColumn<>("State"); private final ObservableList<DataRowModel> dataRows = FXCollections.observableArrayList( new DataRowModel("Concinna", false), new DataRowModel("Concinna", false), new DataRowModel("Concinna", false), new DataRowModel("Concinna", false), new DataRowModel("Concinna", false) ); public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { Scene scene = new Scene(new Group()); stage.setTitle("Table View Sample"); stage.setWidth(500); stage.setHeight(500); tableDataRow.setItems(dataRows); tableDataRowNameColumn.setCellValueFactory(f -> f.getValue().getName()); tableDataRowStateColumn.setCellValueFactory(f -> f.getValue().getState()); tableDataRow.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); tableDataRow.getSelectionModel().getSelectedItems() .addListener((ListChangeListener.Change<? extends DataRowModel> c) -> { while (c.next()) { c.getRemoved().stream().forEach(remitem -> remitem.setSelected(false)); c.getAddedSubList().stream().forEach(additem -> additem.setSelected(true)); } }); tableDataRow.getColumns().addAll(tableDataRowNameColumn, tableDataRowStateColumn); ((Group) scene.getRoot()).getChildren().addAll(tableDataRow); stage.setScene(scene); stage.show(); } public static class DataRowModel { private StringProperty name = new SimpleStringProperty(this, "name", ""); private BooleanProperty selected = new SimpleBooleanProperty(this, "selected", true); private StringProperty state = new SimpleStringProperty(this, "state", ""); public DataRowModel(String name, boolean selected) { this.name.setValue(name); this.selected.setValue(selected); this.selected.addListener((observable, oldVal, newVal) -> { getState(); // Refresh State value }); } public StringProperty getName() { return name; } public BooleanProperty isSelected() { return selected; } public void setSelected(boolean selected) { if (this.selected.getValue() != selected) this.selected.setValue(selected); } public StringProperty getState() { String stateStr = ""; if (selected.getValue()) stateStr += "Selected"; state.setValue(stateStr); return state; } } } 绑定到州列。

    没有上下文,使用这个selected-property的原因似乎很愚蠢。但是,还有各种其他代码片段,其中ChangeListeners绑定到selected-property。

    SSCCE准备好运行:

    chrome.runtime.connect

1 个答案:

答案 0 :(得分:2)

我能够通过编辑Oracle的Person tableview示例来生成它。

这是一个错误,以https://bugs.openjdk.java.net/browse/JDK-8096787提交,并在 8u60 版本中修复,预计将于2015年8月发布。