2017-01-02 104 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的方法,我想我得到你想要的告诉,但不明白我应该如何实现它可以通过编辑上面的代码,如果可能的话,可以显示我 –