Javafx:如何用地图填充 TableView?
Javafx: How to populate a TableView with a map?
我在尝试使用 map 填充 TableView 时遇到问题。我一直在看关于堆栈溢出和其他页面的不同类型的问题,但我的大脑似乎没有得到它。
我有一个 class,它包含一个以产品名称为键、以正常价格为值的地图。我创建了一个 table 视图,其中包含名称列和价格主列,分为正常列和新列两列,如下所示。
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”。有没有人对如何制作最后的代码有任何建议?或者向正确的方向发送我?
提前致谢!
这是我迄今为止尝试过的方法。但实际上我无法理解下面这段代码中发生的事情。我希望它会在开始时用名称填充 table。运气不好。
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;
}
我在尝试使用 map
我有一个 class,它包含一个以产品名称为键、以正常价格为值的地图。我创建了一个 table 视图,其中包含名称列和价格主列,分为正常列和新列两列,如下所示。
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”。有没有人对如何制作最后的代码有任何建议?或者向正确的方向发送我?
提前致谢!
这是我迄今为止尝试过的方法。但实际上我无法理解下面这段代码中发生的事情。我希望它会在开始时用名称填充 table。运气不好。
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;
}