当前位置: 首页 > 知识库问答 >
问题:

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

王兴庆
2023-03-14

我跟踪过这个帖子

用tableview绑定hashmap(JavaFX)

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

TableView通过从Map.EntrySet()创建ObservableList并将该ObservableList传递给TableView的构造函数,从称为MapHashMap接收其数据。(代码如下)

但是,尽管它是一个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();
    }

}

这正是将hashmap与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中的列标题按一列对数据进行排序时,新的更新值将在表数据重新排序后出现。

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

谢谢你,

标记

共有1个答案

邹禄
2023-03-14

ObservableMap与侦听器一起使用,使TableView项和映射的键保持相同,并将CellValueFactory绑定一起使用。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);
 类似资料:
  • 第一个类称为FileReader,它读取一个逐行写入的txt文件,我们需要的每个字段都用“;”分隔,例如(“哥伦比亚大学”;“美国”;78.86;2012)。每行包含2个字符串(大学名和国家)和2个数字(分数和年份)。FileReader类在读取txt文件后,在ArrayList中返回其内容。 该作业的第二个类称为UniversityScores,它有4个字段(uniname、country、sc

  • 问题内容: 如果我创建一个新的HashMap和一个新的List,然后使用一些任意键将List放置在Hashmap中,然后再调用会影响我放置在HashMap中的内容吗? 更深层的问题是:当我向HashMap中添加某些内容时,是复制并放置了一个新对象,还是放置了对原始对象的引用? 谢谢! 问题答案: 这里发生的事情是您在哈希图中放置了 指向 列表的 指针 ,而不是列表本身。 当您定义 您正在定义指向列

  • 我想在JavaFX中显示内容。下面是我用来将内容设置到表列中的代码。我遇到的问题是,它只显示一行。循环只迭代了5次:每次它都会获取的第一个值。 如果忽略行,则循环将迭代中的所有内容。

  • 问题内容: 我有一个哈希图,我想复制该哈希图以用于其他用途。但是,每当我复制并重复使用它时,它也会更改原始内容。这是为什么? 提前致谢 问题答案: 您要做的不是创建地图的副本,而是创建地图的副本。当两个引用指向同一对象时,对一个对象的更改将在另一个对象中反映出来。 解决方案1:如果这是从某种简单类型到另一种类型的Map,则应改为: 这称为复制构造函数。几乎所有标准的Collection和Map实现

  • 问题内容: 我只是想知道,如果一个键会发生什么是可变的,测试程序如下证明,我无法理解当两个平等和方法返回true和值相同,为什么回报。 这个输出: 是否6 6是 问题答案: 该javadoc的解释它 注意:如果将可变对象用作地图键,则必须格外小心。如果在对象是映射中的键的情况下以影响等值比较的方式更改对象的值,则不会指定映射的行为。 基本上,不要在地图中使用可变对象作为键,否则会被烧死 推断一下,

  • 我如何从一个HashMap填充JList而只在列表中显示值呢?