使用HashMap填充TableView,HashMap将在HashMap更改时更新

我关注过这篇文章

使用tableview绑定hashmap(JavaFX)

并创建了一个由HashMap数据填充的TableView。

TableView通过从map.entrySet()创建一个ObservableList并将该ObservableList移交给TableView的构造函数,从名为mapHashMap接收其数据。 (代码如下)

但是,虽然它是带有SimpleStringPropertyObservableList ,但是当对底层HashMap进行更改时,TableView不会更新。

这是我的代码:

 public class MapTableView extends Application { @Override public void start(Stage stage) throws Exception { try { // sample data Map map = new HashMap(); map.put("one", "One"); map.put("two", "Two"); map.put("three", "Three"); // use fully detailed type for Map.Entry TableColumn<Map.Entry, String> column1 = new TableColumn("Key"); column1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry, String>, ObservableValue>() { @Override public ObservableValue call(TableColumn.CellDataFeatures<Map.Entry, String> p) { // this callback returns property for just one cell, you can't use a loop here // for first column we use key return new SimpleStringProperty(p.getValue().getKey()); } }); TableColumn<Map.Entry, String> column2 = new TableColumn("Value"); column2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry, String>, ObservableValue>() { @Override public ObservableValue call(TableColumn.CellDataFeatures<Map.Entry, String> p) { // for second column we use value return new SimpleStringProperty(p.getValue().getValue()); } }); ObservableList<Map.Entry> items = FXCollections.observableArrayList(map.entrySet()); final TableView<Map.Entry> table = new TableView(items); table.getColumns().setAll(column1, column2); Button changeButton = new Button("Change"); changeButton.setOnAction((ActionEvent e) -> { map.put("two", "2"); System.out.println(map); }); VBox vBox = new VBox(8); vBox.getChildren().addAll(table, changeButton); Scene scene = new Scene(vBox, 400, 400); stage.setScene(scene); stage.show(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { launch(); } } 

这正是来自Binding hashmap with tableview(JavaFX)的代码,除了我添加了以下按钮:

  Button changeButton = new Button("Change"); changeButton.setOnAction((ActionEvent e) -> { map.put("two", "2"); System.out.println(map); }); 

然后我将其添加到带有TableView的VBox中。

单击该按钮时, TableView不会更新。 但是,由于System.out.println(map)输出,我可以validation底层HashMap确实已更改。 此外,当我单击TableView的列标题以按一列对数据进行排序时,在重新排序表数据后会出现新的更新值。

如何在更改基础地图时自动更新表格?

谢谢,

标记

使用带有监听器的ObservableMap ,该监听器保持TableView项和映射的键相同,并将cellValueFactoryBindings.valueAt cellValueFactory使用,例如:

 ObservableMap map = FXCollections.observableHashMap(); ObservableList keys = FXCollections.observableArrayList(); map.addListener((MapChangeListener.Change change) -> { boolean removed = change.wasRemoved(); if (removed != change.wasAdded()) { // no put for existing key if (removed) { keys.remove(change.getKey()); } else { keys.add(change.getKey()); } } }); map.put("one", "One"); map.put("two", "Two"); map.put("three", "Three"); final TableView table = new TableView<>(keys); TableColumn column1 = new TableColumn<>("Key"); // display item value (= constant) column1.setCellValueFactory(cd -> Bindings.createStringBinding(() -> cd.getValue())); TableColumn column2 = new TableColumn<>("Value"); column2.setCellValueFactory(cd -> Bindings.valueAt(map, cd.getValue())); table.getColumns().setAll(column1, column2); 

这将更新你的tableView。

 changeButton.setOnAction(e -> { map.put("two", "2"); table.getColumns().setAll(column1, column2); System.out.println(map); });