且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

JavaFX:使用HashMap绑定将行添加到TableView

更新时间:2023-12-06 16:02:10

如果使用ObservableMaps的ObservableList作为您的TableView的数据结构

  ObservableList< ObservableMap> rowMaps = FXCollections.observableArrayList(); 
tableView.setItems(rowMaps);

并实现您自己的ObservableMapValueFactory

  import javafx.beans.property.ObjectProperty; 
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableMap;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.util.Callback;

public class ObservableMapValueFactory< V>实现
回调< TableColumn.CellDataFeatures< ObservableMap,V>,ObservableValue< V> {

private final Object key;

public ObservableMapValueFactory(Object key){
this.key = key;
}

@Override
public ObservableValue< V>调用(CellDataFeatures< ObservableMap,V> features){
final ObservableMap map = features.getValue();
final ObjectProperty< V> property = new SimpleObjectProperty< V>((V)map.get(key));
map.addListener(new MapChangeListener< Object,V>(){
public void onChanged(更改<?,?扩展V>更改){
if(key.equals(change.getKey ())){
property.set((V)map.get(key));
}
}
});
返回属性;


code


然后将其设置为单元格值工厂列(s)

  column.setCellValueFactory(new ObservableMapValueFactory< String>(columnId)); 

您的数据的所有更改都反映在TableView中,甚至只会影响ObservableMaps的更改。


Suppose that I have a map collection:

ObserableHashMap<K,V> map = FXCollections.observableHashMap();

I put 1 record into this map during fxml controller initialization, then wrap it as ObservableList:

ObservableList<ObserableHashMap.Entry<K,V>> list = FXCollections.observableArrayList(map.entrySet());

then setitems for my tableView.setItems(list);

Everything is fine when I run this JavaFX app and 1 record is showing.

Question is that:

When I add more records later to my map, my TableView will not refresh these records.

How could I bind a dynamical map collection into my TableView?

Thanks

If you use an ObservableList of ObservableMaps as your TableView's data structure

ObservableList<ObservableMap> rowMaps = FXCollections.observableArrayList();
tableView.setItems(rowMaps);

and implement your own ObservableMapValueFactory

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableMap;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.util.Callback;

public class ObservableMapValueFactory<V> implements
        Callback<TableColumn.CellDataFeatures<ObservableMap, V>, ObservableValue<V>> {

    private final Object key;

    public ObservableMapValueFactory(Object key) {
        this.key = key;
    }

    @Override
    public ObservableValue<V> call(CellDataFeatures<ObservableMap, V> features) {
        final ObservableMap map = features.getValue();
        final ObjectProperty<V> property = new SimpleObjectProperty<V>((V) map.get(key));
        map.addListener(new MapChangeListener<Object, V>() {
            public void onChanged(Change<?, ? extends V> change) {
                if (key.equals(change.getKey())) {
                    property.set((V) map.get(key));
                }
            }
        });
        return property;
    }
}

and then set it as the cell value factory for your column(s)

column.setCellValueFactory(new ObservableMapValueFactory<String>(columnId));

all changes to your data are reflected in the TableView, even changes only affecting the ObservableMaps.