使用将在 HashMap 更改时更新的 HashMap 填充 TableView
Populating a TableView with a HashMap that will update when HashMap changes
我已经关注了这个post
Binding hashmap with tableview (JavaFX)
并创建了一个由 HashMap 中的数据填充的 TableView。
TableView
通过从 map.entrySet()
创建一个 ObservableList
并传递 ObservableList
来从名为 map
的 HashMap
接收数据TableView
的构造函数。 (代码如下)
但是,尽管它是一个 ObservableList
和 SimpleStringProperty
,但当对底层 HashMap 进行更改时,TableView 不会更新。
这是我的代码:
public class MapTableView extends Application {
@Override
public void start(Stage stage) throws Exception {
try {
// sample data
Map<String, String> map = new HashMap<>();
map.put("one", "One");
map.put("two", "Two");
map.put("three", "Three");
// use fully detailed type for Map.Entry<String, String>
TableColumn<Map.Entry<String, String>, String> column1 = new TableColumn<>("Key");
column1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry<String, String>, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Map.Entry<String, String>, 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, String>, String> column2 = new TableColumn<>("Value");
column2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry<String, String>, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Map.Entry<String, String>, String> p) {
// for second column we use value
return new SimpleStringProperty(p.getValue().getValue());
}
});
ObservableList<Map.Entry<String, String>> items = FXCollections.observableArrayList(map.entrySet());
final TableView<Map.Entry<String,String>> 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
没有更新。但是,我可以验证底层 HashMap
确实由于 System.out.println(map)
输出而发生了变化。此外,当我单击 TableView
中的列 header 以按一列对数据进行排序时,新的更新值出现在 table 数据为 re-sorted.[=27 之后=]
如何在基础地图更改时自动更新 table?
谢谢,
马克
这将更新您的 tableView。
changeButton.setOnAction(e -> {
map.put("two", "2");
table.getColumns().setAll(column1, column2);
System.out.println(map);
});
将 ObservableMap
与保持 TableView
项目和地图键相同的侦听器一起使用,并将 cellValueFactory
与 Bindings.valueAt
一起使用,例如:
ObservableMap<String, String> map = FXCollections.observableHashMap();
ObservableList<String> keys = FXCollections.observableArrayList();
map.addListener((MapChangeListener.Change<? extends String, ? extends String> 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<String> table = new TableView<>(keys);
TableColumn<String, String> column1 = new TableColumn<>("Key");
// display item value (= constant)
column1.setCellValueFactory(cd -> Bindings.createStringBinding(() -> cd.getValue()));
TableColumn<String, String> column2 = new TableColumn<>("Value");
column2.setCellValueFactory(cd -> Bindings.valueAt(map, cd.getValue()));
table.getColumns().setAll(column1, column2);
我已经关注了这个post
Binding hashmap with tableview (JavaFX)
并创建了一个由 HashMap 中的数据填充的 TableView。
TableView
通过从 map.entrySet()
创建一个 ObservableList
并传递 ObservableList
来从名为 map
的 HashMap
接收数据TableView
的构造函数。 (代码如下)
但是,尽管它是一个 ObservableList
和 SimpleStringProperty
,但当对底层 HashMap 进行更改时,TableView 不会更新。
这是我的代码:
public class MapTableView extends Application {
@Override
public void start(Stage stage) throws Exception {
try {
// sample data
Map<String, String> map = new HashMap<>();
map.put("one", "One");
map.put("two", "Two");
map.put("three", "Three");
// use fully detailed type for Map.Entry<String, String>
TableColumn<Map.Entry<String, String>, String> column1 = new TableColumn<>("Key");
column1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry<String, String>, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Map.Entry<String, String>, 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, String>, String> column2 = new TableColumn<>("Value");
column2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry<String, String>, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Map.Entry<String, String>, String> p) {
// for second column we use value
return new SimpleStringProperty(p.getValue().getValue());
}
});
ObservableList<Map.Entry<String, String>> items = FXCollections.observableArrayList(map.entrySet());
final TableView<Map.Entry<String,String>> 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
没有更新。但是,我可以验证底层 HashMap
确实由于 System.out.println(map)
输出而发生了变化。此外,当我单击 TableView
中的列 header 以按一列对数据进行排序时,新的更新值出现在 table 数据为 re-sorted.[=27 之后=]
如何在基础地图更改时自动更新 table?
谢谢,
马克
这将更新您的 tableView。
changeButton.setOnAction(e -> {
map.put("two", "2");
table.getColumns().setAll(column1, column2);
System.out.println(map);
});
将 ObservableMap
与保持 TableView
项目和地图键相同的侦听器一起使用,并将 cellValueFactory
与 Bindings.valueAt
一起使用,例如:
ObservableMap<String, String> map = FXCollections.observableHashMap();
ObservableList<String> keys = FXCollections.observableArrayList();
map.addListener((MapChangeListener.Change<? extends String, ? extends String> 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<String> table = new TableView<>(keys);
TableColumn<String, String> column1 = new TableColumn<>("Key");
// display item value (= constant)
column1.setCellValueFactory(cd -> Bindings.createStringBinding(() -> cd.getValue()));
TableColumn<String, String> column2 = new TableColumn<>("Value");
column2.setCellValueFactory(cd -> Bindings.valueAt(map, cd.getValue()));
table.getColumns().setAll(column1, column2);