2012-06-19 64 views
13

Tôi có một TableView liên quan đến một TreeView. Mỗi lần một nút trong TreeView được chọn, TableView được làm mới với dữ liệu khác nhau.Javafx: Sắp xếp lại một cột trong một TableView

Tôi có thể sắp xếp bất kỳ cột nào trong Bảng nhìn, chỉ cần nhấn tiêu đề cột tương ứng. Điều đó hoạt động tốt.

Nhưng: khi tôi chọn một nút khác trong chế độ xem dạng cây, dù các tiêu đề cột vẫn hiển thị như được sắp xếp. Dữ liệu thì không.

Có cách nào để thực thi lệnh sắp xếp theo thứ tự do người dùng thực hiện mỗi lần dữ liệu thay đổi không?

+0

độc giả tương lai:!. Tiết kiệm cho mình một chút thời gian và [di chuyển xuống] (http://stackoverflow.com/a/29743777/309308) –

Trả lời

15

Ok, tôi đã tìm cách thực hiện. Tôi sẽ tóm tắt nó đây trong trường hợp nó rất hữu ích cho người khác:

Trước bạn cập nhật các nội dung của TableView, bạn phải lưu các sortcolum (nếu có) và sortType:

 TableView rooms; 
     ... 
     TableColumn sortcolumn = null; 
     SortType st = null; 
     if (rooms.getSortOrder().size()>0) { 
      sortcolumn = (TableColumn) rooms.getSortOrder().get(0); 
      st = sortcolumn.getSortType(); 
     } 

Sau đó, sau khi bạn cập nhật dữ liệu trong TableView, bạn phải khôi phục trạng thái cột sắp xếp bị mất và thực hiện sắp xếp.

 if (sortcolumn!=null) { 
      rooms.getSortOrder().add(sortcolumn); 
      sortcolumn.setSortType(st); 
      sortcolumn.setSortable(true); // This performs a sort 
     } 

Tôi không tính đến khả năng có nhiều cột trong sắp xếp, nhưng điều này rất đơn giản để làm với thông tin này.

+0

'rooms.getSortOrder() isEmpty() 'sẽ thanh lịch hơn 'rooms.getSortOrder(). size()> 0'. Bên cạnh đó, olution của bạn chỉ giữ lại một cột sắp xếp thay vì tất cả chúng. – glglgl

+0

Cách tiếp cận này đã được thử nhưng một vấn đề đang xảy ra https://stackoverflow.com/questions/46160528/exception-after-retaining-sorting-column-of-tableview-in-javafx –

6

Nếu TableView của bạn không được reinitialized, bạn cũng có thể làm như sau:

TableColumn<BundleRow, ?> sortOrder = rooms.getSortOrder().get(0); 
rooms.getSortOrder().clear(); 
rooms.getSortOrder().add(sortOrder); 
6

Các ví dụ về fornacif công trình, nhưng không phải nếu có nhiều hơn một thứ tự sắp xếp (thử Shift-click vào một cột thứ hai để tạo thứ tự sắp xếp thứ cấp).

Để làm một tái sắp xếp trên tất cả các cột bạn sẽ cần phải làm một cái gì đó như thế này:

List<TableColumn<Room, ?>> sortOrder = new ArrayList<>(roomTable.getSortOrder()); 
roomTable.getSortOrder().clear(); 
roomTable.getSortOrder().addAll(sortOrder); 
+0

khi tôi thử mã này hiển thị lỗi của nó cho phần ArratList <> (roomTable.getSortOrder()); nó hoạt động khi tôi sử dụng ArratList > (roomTable.getSortOrder()); bạn có thể giải thích cho tôi lý do – learner

+0

Tôi nghĩ cú pháp <> chỉ hoạt động cho phiên bản Java sau này, bạn phải sử dụng Java 6 hoặc 7? –

2
câu trả lời

Marco Jakob là tốt cho hầu hết các trường hợp, nhưng tôi thấy rằng tôi cần thiết để tạo ra một so sánh phù hợp thứ tự sắp xếp bảng để linh hoạt hơn. Sau đó, bạn có thể sử dụng bất kỳ phương pháp nào để so sánh để phân loại, tìm kiếm, v.v. Để tạo bộ so sánh, tôi mở rộng lớp ComparatorChain từ Bộ sưu tập chung của apache để dễ dàng phân loại nhiều cột. Nó trông như thế này

public class TableColumnListComparator extends ComparatorChain { 
    public TableColumnListComparator(ObservableList<? extends TableColumn> columns) { 
     // Get list of comparators from column list. 
     for (TableColumn column : columns) { 
      addComparator(new ColumnComparator(column)); 
     } 
    } 

    /** 
    * Compares two items in a table column as if they were being sorted in the TableView. 
    */ 
    private static class ColumnComparator implements Comparator { 

     private final TableColumn column; 

     /** 
     * Default Constructor. Creates comparator based off given table column sort order. 
     * 
     * @param column 
     */ 
     public ColumnComparator(TableColumn column) { 
      this.column = column; 
     } 

     @Override 
     public int compare(Object o1, Object o2) { 
      // Could not find a way to do this without casts unfortunately 
      // Get the value of the column using the column's cell value factory. 
      final ObservableValue<?> obj1 = (ObservableValue) column.getCellValueFactory().call(
        new TableColumn.CellDataFeatures(column.getTableView(), column, o1)); 
      final ObservableValue<?> obj2 = (ObservableValue) column.getCellValueFactory().call(
        new TableColumn.CellDataFeatures(column.getTableView(), column, o2)); 
      // Compare the column values using the column's given comparator. 
      final int compare = column.getComparator().compare(obj1.getValue(), obj2.getValue()); 
      // Sort by proper ascending or descending. 
      return column.getSortType() == TableColumn.SortType.ASCENDING ? compare : -compare; 
     } 
    } 
} 

Bạn có thể sau đó sắp xếp bất cứ lúc nào với

Collections.sort(backingList, new TalbeColumnListComparator(table.getSortOrder()); 

Tôi sử dụng này để sắp xếp nhiều danh sách với cùng một loại, sắp xếp trên chủ đề nền, làm cập nhật hiệu quả mà không cần toàn bộ danh sách, vv Tôi nghĩ rằng sẽ có một số cải tiến đối với việc sắp xếp bảng trong Javafx 8 vì vậy điều này sẽ không cần thiết trong tương lai.

11

tôi đã cùng một vấn đề và phát hiện ra rằng sau khi cập nhật các dữ liệu bạn chỉ cần gọi hàm sort() trên xem bảng:

TableView rooms; 
... 
// Update data of rooms 
... 
rooms.sort() 

Quan điểm bảng biết các cột để phân loại như vậy chức năng sắp xếp sẽ sắp xếp dữ liệu mới theo thứ tự mong muốn. Chức năng này chỉ có sẵn trong Java 8.

3

Nếu bạn sử dụng phương thức TableView.setItems(), nó xuất hiện để đặt lại một số khía cạnh của TableView. Để ObservableList trong TableView tại chỗ, xóa nội dung của nó và sau đó thêm các mục mới của bạn. Sau đó, TableView.sort() sẽ vẫn biết những cột nào đã được sắp xếp trước đó và nó sẽ hoạt động. Như thế này:

tableView.getItems().clear(); 
    tableView.getItems().addAll(newTableData); 
    tableView.sort(); 
Các vấn đề liên quan