将嵌套对象属性绑定到JavaFx中的TableView

时间:2014-07-15 22:32:14

标签: java javafx

我有下一堂课

public class ProductStockDto extends 

    private Long id;
    private Long amount;
    private ProductDto product;
    private StockDto stock;

    //getters and setters...
}

在JavaFx中我有我的表,我想将product.name属性绑定到列,就像这样。

ObservableList<ProductStockDto> data = FXCollections.observableArrayList();
data.addAll(products);
nameColumn.setCellValueFactory(new PropertyValueFactory("product.name"));
productTable.setItems(data);

但是当我这样做时,TableView上的行显示为空白。

有人可以帮我这个吗?我想绑定嵌套对象属性,Java Swing就像$ {product.name}

感谢。

9 个答案:

答案 0 :(得分:5)

Javafx不支持此格式,作为解决方法,您可以尝试以下方式:

nameColumn.setCellValueFactory(new Callback<CellDataFeatures<ProductStockDto, String>, 
                                                         ObservableValue<String>>() {  
    @Override  
    public ObservableValue<String> call(CellDataFeatures<ProductStockDto, String> data){  
         return data.getValue().getProducts().nameProperty();  
    }  
});  

ProductDto将有

public class ProductDto{

    private StringProperty name = new SimpleStringProperty("Itachi");

    public String getName() {
        return name.get();
    }

    public void setStreet(String name) {
        this.name.set(name);
    }

    public StringProperty nameProperty(){
        return name;
    }
}

答案 1 :(得分:4)

作为变体,您可以使用合成属性。

让我们将其命名为&#39; productName&#39;:

nameColumn.setCellValueFactory(new PropertyValueFactory("productName"));

在您的ProductStockDto课程中有类似的内容:

public String getProductName() {
   return product.getName();
}

答案 2 :(得分:2)

TableColumn<ProductStockDto , String> ProductNameCol = new ProductNameCol ("Product Name");

ProductNameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ProductStockDto , String>, ObservableValue<String>>() {

    @Override
    public ObservableValue<String> call(TableColumn.CellDataFeatures<ProductStockDto , String> param) {
        return new SimpleObjectProperty<>(param.getValue().ProductDto ().getName());

    }
});

答案 3 :(得分:1)

您可以简单地使用:

nameColumn.setCellValueFactory(new PropertyValueFactory("product"));

这将使用对象产品中的toString()方法。但是,如果只进行此操作,则可能会以“ProductDto @ abcef123”结尾,这是toString方法的复杂对象的默认返回。

然后你可以做的是覆盖toString方法:

@Override
public String toString(){
    return //Whatever you want to show
}

我一直坚持这个,最终找到了这个解决方案。 希望这会有所帮助。

答案 4 :(得分:1)

我遇到了同样的问题,无法以任何建议的方式使其工作,但是,如果我们实例化列并具有嵌套属性(例如在Employee类中),对我有什么作用?

@FXML
private TableColumn<Employee, String> columnEmpName;
@FXML
private TableColumn<Employee, String> columnEmpLastName;
@FXML
private TableColumn<Employee, String> columnEmpJobDesc;

班级是:

public class Employee {
   private String name;
   private String lastName;
   .
   .
   private EmployeeJobDescription jobDesc; //this one is nested
}

我已经从为该属性选择的字符串中提取了ObservableValue<String>

columnEmpName.setCellValueFactory(new PropertyValueFactory<Employee, String>("name"));
columnEmpLastName.setCellValueFactory(new PropertyValueFactory<Employee, String>("lastname"));
columnEmpJobDesc.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getJobDesc().getJobDescription()));

EmployeeJobDescription将与所有获取器和设置器一起使用

public class EmployeeJobDescription {

private Integer id;
private String jobDescription;

public EmployeeJobDescription(Integer id) {
    this.id = id;
}

public EmployeeJobDescription(Integer id, String jobDescription) {
    this.id = id;
    this.jobDescription = jobDescription;
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getJobDescription() {
    return jobDescription;
}

public void setJobDescription(String jobDescription) {
    this.jobDescription = jobDescription;
}

}

在这篇文章中了解了如何做:

Convert a String to an ObservableValue

答案 5 :(得分:1)

如果您有一个对象和另一个类型为String的属性(例如:在ProductDto类中为整数的数字“ productDto_nr”),则可以使用StringProperty类型来解决。

nameColumn.setCellValueFactory(new Callback<CellDataFeatures<ProductStockDto, String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(CellDataFeatures<ProductStockDto, String> data) {
        StringProperty sp = new SimpleStringProperty();
        sp.setValue(String.valueOf(data.getValue().getProduct().getProductDto_nr()));
        return sp;
    }
});

答案 6 :(得分:0)

如果我们有一个不是原始java数据类型的属性,那么我们不能通过步骤(例如ProductStockDto.product.name)直接访问它,其中ProductStockDto是一个实体,产品是另一个实体,产品具有属性字符串名称。 这里。 我需要在TableView中呈现名称列,就像我之前的回复中所回答的那样。

此外,您可以使用:javafx.beans.property.adapter包将javabeans对象转换为javafx bean对象属性。如果你想要更复杂的代码。

答案 7 :(得分:0)

请尝试以下使用Apache BeanUtils的代码。

public class StringCellValueFactory implements 
  Callback<CellDataFeatures<Object, String>, ObservableValue<String>> {
    private String property;

    public StringCellValueFactory(String property) {
        this.property = property;
    }

    public ObservableValue<String> call(CellDataFeatures<Object, String> param) {
        Object value = param.getValue();
        String stringValue = null;
        try {
            stringValue = BeanUtils.getNestedProperty(value, property);
        } catch (Exception e) {
            logger.error("Error in StringCellValueFactory", e);
        }

        return new SimpleStringProperty(stringValue);
    }
}

答案 8 :(得分:0)

没有必要更改常规Java类:

 nameCol.setCellValueFactory(new Callback<CellDataFeatures<ProductDto, String>, ObservableValue<String>>() {
     public ObservableValue<String> call(CellDataFeatures<ProductDto, String> p) {
         return new ReadOnlyObjectWrapper(p.getValue().getCost());
     }
  });