2017-01-02 135 views
0

我想創建具有動態列和行的表視圖,所以我想從後臺更新每個單元格值,只要我從我的數據源中獲取值這是我在揮杆setValueAt()中使用的。 所以基本上我不想創建模型類,因爲我的列不固定,行也不固定,我不想重新創建表視圖來更新表視圖中的一行,所以請指導我,因爲我是新的javafx表視圖。在情況下,如果你不明白我的問題,那麼請評論如何更新表中的每一行的值JAVAFX

感謝

編輯源代碼示例

import javafx.application.Application; 
import javafx.beans.property.ReadOnlyObjectWrapper; 
import javafx.collections.*; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.stage.Stage; 

import java.util.*; 

public class DynamicTableView extends Application { 

private static final int N_COLS = 5; 
private static final int N_ROWS = 1000; 

public void start(Stage stage) throws Exception { 
    TestDataGenerator dataGenerator = new TestDataGenerator(); 

    TableView<ObservableList<String>> tableView = new TableView<>(); 

    // add columns 
    List<String> columnNames = dataGenerator.getNext(N_COLS); 
    for (int i = 0; i < columnNames.size(); i++) { 
     final int finalIdx = i; 
     TableColumn<ObservableList<String>, String> column = new TableColumn<>(
       columnNames.get(i) 
     ); 
     column.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().get(finalIdx))); 
     tableView.getColumns().add(column); 
    } 

    // add data 
    for (int i = 0; i < N_ROWS; i++) { 
     tableView.getItems().add(
       FXCollections.observableArrayList(
         dataGenerator.getNext(N_COLS) 
       ) 
     ); 
    } 

    tableView.setPrefHeight(200); 

    Scene scene = new Scene(tableView); 
    stage.setScene(scene); 
    stage.show(); 
} 

public static void main(String[] args) { 
    launch(args); 
} 

private static class TestDataGenerator { 

    private static final String[] LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tempus cursus diam ac blandit. Ut ultrices lacus et mattis laoreet. Morbi vehicula tincidunt eros lobortis varius. Nam quis tortor commodo, vehicula ante vitae, sagittis enim. Vivamus mollis placerat leo non pellentesque. Nam blandit, odio quis facilisis posuere, mauris elit tincidunt ante, ut eleifend augue neque dictum diam. Curabitur sed lacus eget dolor laoreet cursus ut cursus elit. Phasellus quis interdum lorem, eget efficitur enim. Curabitur commodo, est ut scelerisque aliquet, urna velit tincidunt massa, tristique varius mi neque et velit. In condimentum quis nisi et ultricies. Nunc posuere felis a velit dictum suscipit ac non nisl. Pellentesque eleifend, purus vel consequat facilisis, sapien lacus rutrum eros, quis finibus lacus magna eget est. Nullam eros nisl, sodales et luctus at, lobortis at sem.".split(" "); 

    private int curWord = 0; 

    List<String> getNext(int nWords) { 
     List<String> words = new ArrayList<>(); 

     for (int i = 0; i < nWords; i++) { 
      if (curWord == Integer.MAX_VALUE) { 
       curWord = 0; 
      } 

      words.add(LOREM[curWord % LOREM.length]); 
      curWord++; 
     } 

     return words; 
    } 
} 
} 

回答

1

由於the javadoc說,持有該表的模型是項屬性。你可以這樣做:

table.getItems() 

並使用它(添加,刪除,清除...)。

正如我在你的例子中看到的,你有一個字符串表。爲了選擇每列顯示的內容,您必須使用setValueFactory()。這樣每個列將知道如何呈現每個值。比方說,你有字符串:

"Hi how are you?" 

而你正在嘗試做的拿到4列是這樣的:

hi | how | are | you? 

你可以只itetate在每一列,並設置拆分param.getValue一個cellValueFactory ()並採取其相應的索引。

編輯:加入您的changeValueAt():

public class DynamicTableView extends Application { 

private static final int N_COLS = 5; 
private static final int N_ROWS = 1000; 

public void start(Stage stage) throws Exception { 
    TestDataGenerator dataGenerator = new TestDataGenerator(); 

    TableView<ObservableList<String>> tableView = new TableView<>(); 

    // add columns 
    List<String> columnNames = dataGenerator.getNext(N_COLS); 
    for (int i = 0; i < N_COLS; i++) { 
     final int index = i; 
     TableColumn<ObservableList<String>, String> column = new TableColumn<>(columnNames.get(i)); 
     column.setCellValueFactory(cellData -> new ReadOnlyObjectWrapper<>((cellData.getValue().get(index)))); 
     tableView.getColumns().add(column); 
    } 

    // add data 
    for (int i = 0; i < N_ROWS; i++) { 
     tableView.getItems().add(FXCollections.observableArrayList(dataGenerator.getNext(N_COLS))); 
    } 

    tableView.setPrefHeight(200); 

    Scene scene = new Scene(tableView); 
    stage.setScene(scene); 
    stage.show(); 
    changeValueAt(0,0, "thisIsMyNewValue", tableView); 

} 

private static void changeValueAt(int row, int col, String value, TableView<ObservableList<String>> table){ 
    ObservableList newData = table.getItems().get(row); 
    newData.set(col, value); 
    table.getItems().set(row, newData); 

} 

public static void main(String[] args) { 
    launch(args); 

} 

private static class TestDataGenerator { 

    private static final String[] LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tempus cursus diam ac blandit. Ut ultrices lacus et mattis laoreet. Morbi vehicula tincidunt eros lobortis varius. Nam quis tortor commodo, vehicula ante vitae, sagittis enim. Vivamus mollis placerat leo non pellentesque. Nam blandit, odio quis facilisis posuere, mauris elit tincidunt ante, ut eleifend augue neque dictum diam. Curabitur sed lacus eget dolor laoreet cursus ut cursus elit. Phasellus quis interdum lorem, eget efficitur enim. Curabitur commodo, est ut scelerisque aliquet, urna velit tincidunt massa, tristique varius mi neque et velit. In condimentum quis nisi et ultricies. Nunc posuere felis a velit dictum suscipit ac non nisl. Pellentesque eleifend, purus vel consequat facilisis, sapien lacus rutrum eros, quis finibus lacus magna eget est. Nullam eros nisl, sodales et luctus at, lobortis at sem." 
      .split(" "); 

    private int curWord = 0; 

    List<String> getNext(int nWords) { 
     List<String> words = new ArrayList<>(); 

     for (int i = 0; i < nWords; i++) { 
      if (curWord == Integer.MAX_VALUE) { 
       curWord = 0; 
      } 

      words.add(LOREM[curWord % LOREM.length]); 
      curWord++; 
     } 

     return words; 
    } 
} 

}

最重要的事情是這樣的:

private static void changeValueAt(int row, int col, String value, TableView<ObservableList<String>> table){ 
    ObservableList newData = table.getItems().get(row); 
    newData.set(col, value); 
    table.getItems().set(row, newData); 

}

的渲染器每次燒製屬性改變。我只需訪問要更改的行上的元素,並在那裏訪問該列中的元素。通過改變它,改變被發現到呈現新值的列。

說明

在TableView中通用類表示在TableView中保持ObservableList類中的通用類型(在項目屬性)。這種類型與行的一致類型,這樣做:

table.getItems().get(0) 

要檢索保持第一行數據,你的情況的ObservableList的對象。這就是爲什麼你的table.getItems()返回

ObservableList<ObservableList<String>> 

(你提供的泛型類型的ObservableList)。

在渲染每一列時,您必須提供一個CellValueFactory,指示TableView泛型類型和列數據類型,然後實現如何從您擁有的信息中獲取單元格值。

所有這些都與屬性一起工作,就像正常的數據類型一樣,但是在更改時觸發事件。這就是爲什麼我的方法有效,一旦你修改了一個屬性,這個屬性觸發了改變的事件和表格重新渲染(簡短的解釋)。這裏的事情是,這種改變不會被傳播,所以通過改變一個列,包含行的列表,每個列都沒有得到通知。這就是爲什麼我已經修改它後再次設置相同的行。

只要理解你的例子是非常罕見的,因爲通常該表擁有普通的POJO,並且與之交互的唯一ObservableList是items屬性。

+0

感謝答案,但是這僅僅是我而尋找解決我的使用情況是完全輸精管grabed的例子 –

+0

我想財產以後類似'setValueAt()'擺動 –

+0

Sorrry的方法,我想我得到你想要的告訴,但不明白我應該如何實現它可以通過編輯上面的代碼,如果可能的話,可以顯示我 –