Javafx:如何用地图填充TableView



我在尝试用映射填充TableView时遇到问题<字符串,双>。我一直在研究关于堆栈溢出和其他页面的不同类型的问题,但我的大脑似乎不明白

我有一个类,它包含一个以产品名称为关键字、以正常价格为值的Map。我创建了一个tableView,它有一个名称列和一个价格主列,分为普通和新两列,如下所示。

public class CreatePricesPane extends GridPane {
private TableView table = new TableView<>();
private PriceList tempPriceList;

public CreatePricesPane(){
this.tempPriceList = Controller.getController().createPriceList();
this.setPadding(new Insets(20));
this.setHgap(70);
this.setVgap(10);
this.setGridLinesVisible(false);
//        this.setPrefSize(800, 500);
this.setStyle("-fx-background-color: #fff");
//All about table
this.table.setEditable(true);
this.table.setItems(this.generateData());
TableColumn<Map,String> nameColumn = new TableColumn("Names");
nameColumn.setMinWidth(300);
TableColumn pricesColumn = new TableColumn("Prices");
TableColumn<Map,Double> normalPriceColumn = new TableColumn("Normal price");
normalPriceColumn.setMinWidth(150);
//        normalPriceColumn.setCellValueFactory(new MapValueFactory<>());
TableColumn newPriceColumn = new TableColumn("New price");
newPriceColumn.setMinWidth(150);
pricesColumn.getColumns().addAll(normalPriceColumn,newPriceColumn);

table.setEditable(true);
table.getSelectionModel().setCellSelectionEnabled(true);
table.getColumns().setAll(nameColumn, pricesColumn);

我用这个方法将Map制作成ObservableList。

private ObservableList<Map<String, Double>> generateData(){
ObservableList<Map<String,Double>> alldata = FXCollections.observableArrayList();
Map<String, Double> map = new HashMap(this.tempPriceList.getPriceListMap());
for (Map.Entry<String, Double> entry : map.entrySet()) {
Map<String, Double> dataRow = new HashMap<>();
dataRow.put(entry.getKey(), entry.getValue());
alldata.add(dataRow);
}
return alldata;
}

这就是我陷入困境的地方。我不知道如何用这个ObservableList填充每个单元格。我知道我必须使用";setCellFactory";在某种程度上。有人对如何制作最后一个代码有什么建议吗?还是把我送到正确的方向?

提前感谢!

这是我迄今为止一直在尝试的。但实际上,我很难理解下面的代码中发生了什么。我希望它能在一开始就用名字填充表格。运气不好。

Callback<TableColumn<Map, String>, TableCell<Map, String>>
cellFactoryForMap = new Callback<TableColumn<Map, String>,
TableCell<Map, String>>() {
@Override
public TableCell call(TableColumn p) {
return new TextFieldTableCell(new StringConverter() {
@Override
public String toString(Object t) {
return t.toString();
}
@Override
public Object fromString(String string) {
return string;
}
});
}
};
nameColumn.setCellFactory(cellFactoryForMap);

为TableView项创建一个真正的数据类型。

public class Item {
private final StringProperty name;
private final DoubleProperty price;
private final DoubleProperty newPrice;
public Item() {
name = new SimpleStringProperty(this, "name");
price = new SimpleDoubleProperty(this, "price");
newPrice = new SimpleDoubleProperty(this, "newPrice");
}
public Item(String name,
double price) {
this();
setName(name);
setPrice(price);
}
public StringProperty nameProperty() {
return name;
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public DoubleProperty priceProperty() {
return price;
}
public double getPrice() {
return price.get();
}
public void setPrice(double price) {
this.price.set(price);
}
public DoubleProperty newPriceProperty() {
return newPrice;
}
public double getNewPrice() {
return newPrice.get();
}
public void setNewPrice(double price) {
this.newPrice.set(price);
}
}

(注意:在现实世界的应用程序中,程序员永远不应该使用double来表示货币金额,因为float和double是不精确的数字,可能会丢失信息。BigDecimal是表示货币的正确类型。(

现在,TableColumns的单元格值工厂变得容易多了:

nameColumn.setCellValueFactory(f -> f.getValue().nameProperty());
pricesColumn.setCellValueFactory(f -> f.getValue().priceProperty());
newPriceColumn.setCellValueFactory(f -> f.getValue().newPriceProperty());

创建这些项目与您已经在做的非常相似,尽管更简单:

private ObservableList<Item> generateData() {
ObservableList<Item> alldata = FXCollections.observableArrayList();
for (Map.Entry<String, Double> entry : map.entrySet()) {
alldata.add(new Item(entry.getKey(), entry.getValue()));
}
return alldata;
}

最新更新