Tôi có một TableView
trong SelectionMode.MULTIPLE
. Sử dụng ListChangeListener
Tôi có thể nắm bắt được nhiều hàng (bằng cách nhấn Shift).
SelectedItems trống nếu có nhiều hàng được chọn bằng các cột khác nhau
Tuy nhiên, giải pháp của tôi chỉ hoạt động nếu các mục đang được chọn trong cùng một cột HOẶC trong khu vực không có cột. Gif để minh hoạ với 4 ví dụ:
- OK: Lựa chọn 3 mục sử dụng phím Shift trong cột State
- OK: Lựa chọn 4 mặt hàng sử dụng phím Shift trong cột IDX
- OK: Chọn 4 mục bằng cách sử dụng Shift bắt đầu từ cột Nhà nước đến khu vực không có cột
- Lỗi: Cố gắng chọn 4 mặt hàng sử dụng phím Shift bắt đầu từ cột State định tại Khoản cột dữ liệu
Vấn đề có vẻ là rằng SelectedItems
-list dường như trống trong ví dụ cuối cùng . Tôi thực sự đánh giá cao sự giúp đỡ của bạn về vấn đề này.
Đây là cách tiếp cận của tôi:
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
}
});
Just for hiểu rõ hơn về mã của tôi: setSelected(...)
lập một BooleanProperty
trên DataRowModel
của tôi đó là ràng buộc đối với Nhà nước-Column.
Nếu không có ngữ cảnh thì lý do sử dụng thuộc tính được chọn này có vẻ khá ngớ ngẩn. Tuy nhiên, có nhiều đoạn mã khác nhau với ChangeListeners được liên kết với thuộc tính đã chọn.
SSCCE sẵn sàng để chạy:
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;
}
}
}
trong khi hình ảnh là tốt đẹp - tốt hơn sẽ là một SSCCE đó chứng tỏ vấn đề: -) – kleopatra
Đã thêm - xóa một số thứ không cần thiết trong SSCCE để lấy mã JavaFX như được cô đặc càng tốt :) – Luke
Tôi đã có thể tạo ra điều này bằng cách chỉnh sửa ví dụ về bảng Person của Oracle. Lỗi này được gửi dưới dạng https://bugs.openjdk.java.net/browse/JDK-8096787 và được sửa trong 8u60. –