2015-06-15 18 views
7

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ụ:

  1. OK: Lựa chọn 3 mục sử dụng phím Shift trong cột State
  2. OK: Lựa chọn 4 mặt hàng sử dụng phím Shift trong cột IDX
  3. 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
  4. 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

Selection of multiple items in different columns

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; 
     } 
    } 
} 
+3

trong khi hình ảnh là tốt đẹp - tốt hơn sẽ là một SSCCE đó chứng tỏ vấn đề: -) – kleopatra

+0

Đã 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

+4

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. –

Trả lời

2

tôi đã có thể tạo ra điều này bằng cách chỉnh sửa Person tableview dụ của Oracle.

Đây là một lỗi, nộp như https://bugs.openjdk.java.net/browse/JDK-8096787, và cố định trong phiên bản 8u60 mà dự kiến ​​sẽ được phát hành vào tháng năm 2015.

+0

@kleopatra bạn được chào đón! –

Các vấn đề liên quan