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

Luk*_*uke 7 java javafx java-8 javafx-8

我有一个TableViewSelectionMode.MULTIPLE.使用ListChangeListener我能够捕获多行的选择(按下Shift).

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

  1. OK:Shift在State列中选择3项
  2. OK:Shift在Idx列中选择4个项目
  3. OK:使用Shift从State列开始到没有列的区域选择4个项目
  4. 错误:尝试使用" Shift状态"列从"数据项"列开始选择4个项目

选择不同列中的多个项目

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

这是我的方法:

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
    }
});
Run Code Online (Sandbox Code Playgroud)

只是为了更好地理解我的代码:setSelected(...)设置一个绑定到State-Column的BooleanPropertymy DataRowModel.

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

SSCCE准备好运行:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Ulu*_*Biy 2

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

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