Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用HashMap填充TableView,该HashMap将在HashMap更改时更新_Java_Javafx_Hashmap_Tableview_Observablelist - Fatal编程技术网

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

Java 使用HashMap填充TableView,该HashMap将在HashMap更改时更新,java,javafx,hashmap,tableview,observablelist,Java,Javafx,Hashmap,Tableview,Observablelist,我关注过这个帖子 并创建了一个由HashMap中的数据填充的TableView TableView通过从map.entrySet()创建一个observeList并将该observeList关闭到TableView的构造函数,从名为map的HashMap接收数据。(代码如下) 但是,尽管它是一个带有SimpleStringPropertys的ObservableList,但当对基础HashMap进行更改时,TableView不会更新 这是我的密码: public class MapTableV

我关注过这个帖子

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

TableView
通过从
map.entrySet()
创建一个
observeList
并将该
observeList
关闭到
TableView
的构造函数,从名为
map
HashMap
接收数据。(代码如下)

但是,尽管它是一个带有
SimpleStringProperty
s的
ObservableList
,但当对基础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();
    }

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

单击按钮时,
TableView
不会更新。但是,我可以验证底层的
HashMap
确实因为
System.out.println(map)
输出而发生了更改。另外,当我单击
TableView
中的列标题按一列对数据进行排序时,表数据重新排序后会出现新的更新值

当基础映射发生更改时,如何使表自动更新

谢谢,


标记这将更新您的tableView

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

使用
observeMap
和监听器,使
TableView
项和映射键保持相同,并使用
cellValueFactory
和,例如:

observeMap=FXCollections.observeHashMap();
ObservableList keys=FXCollections.observableArrayList();

map.addListener((mapchangeStener.change)我没有详细研究这一点,但也许你想使用一个。也许这个答案谢谢。这确实有效。但是,如果我向表中添加一些东西呢?例如,如果我将行
map.put(“二”,“二”)
更改为
map.put(“四”,“四”)
。在这种情况下,表不会更新以反映更改。为什么不更新?不管怎样,我现在知道为什么了。因此我可以将行
table.getColumns().setAll(column1,column2)
更改为
table.setItems(FXCollections.observearraylist(map.entrySet());
但这似乎不美观,因为我正在重新创建ArrayList并用它重新填充表。此外,这样做会“破坏”用户通过单击列标题可能已经建立的任何排序顺序。还有其他方法吗?对于>=8u60的版本,您可能应该替换
getColumns().getColumns().setAll(第1列、第2列)
with
refresh()
谢谢。效果很好!这是一种有趣的方法,将它变成一个字符串表,并为键提供一个单独的ObservableList。我也不知道MapChangeListener和绑定。非常有用,谢谢!我正在尝试理解lambda表达式中的绑定。假设我现在想为
observeMap
其中
Shade
是一个自定义类,具有名为
Description
StringProperty
成员(即
getDescription()
返回一个
String
descriptionProperty()
返回一个
StringProperty
)如何更改行
column2.setCellValueFactory(cd->Bindings.valueAt(map,cd.getValue())
?感谢您提供的见解。不幸的是,绑定API没有提供这种2级绑定,因此您必须通过向映射值的相应属性添加侦听器(并在值更改为其他值时将其从旧值的属性中删除)来自行编程.没有那么复杂,但评论部分不是给出更详细描述的合适位置。
changeButton.setOnAction(e -> {
                map.put("two", "2");
                table.getColumns().setAll(column1, column2);
                System.out.println(map);
});
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);