2014-07-15 54 views
7

我隔壁班的綁定嵌套的對象屬性的TableView在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}

謝謝。

回答

4

這種格式不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; 
    } 
} 
0
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()); 

    } 
}); 
+1

通常情況下,如果答案包括解釋代碼意圖做什麼以及爲什麼解決問題而不介紹其他問題,則答案會更有幫助。 –

0

,如果我們有一個屬性這不是原始的Java數據類型,因此我們無法直接通過步驟訪問它(例如ProductStockDto.product.name),其中ProductStockDto是一個實體,產品是另一個實體和產品具有屬性字符串名稱。 在這裏。 我們需要在T​​ableView中呈現名稱列,正如我在之前的回覆中回答的那樣。

此外,可以使用:javafx.beans.property.adapter包將javabeans對象轉換爲javafx beans對象的屬性。如果你想要更復雜的代碼。

2

您可以簡單地使用:

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

這將使用toString()方法從對象產品。但是,如果僅這樣做,則可能會以類似「ProductDto @ abcef123」的結尾,並且是toString方法的複雜對象的默認返回值。

你可以做的,然後重寫toString方法:

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

我已經堅持了這一點,並最終找到這個解決方案。 希望這會有所幫助。

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); 
    } 
} 
+0

而不是org.apache.commons.beanutils.BeanUtils,org.apache.commons.beanutils.PropertyUtils可以被使用,如果該值是java.util.Date,任何用戶定義的對象等。 –

3

作爲變體,你可以使用合成屬性。

讓它命名爲 '產品名稱':

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

在你ProductStockDto類有這樣的事情:

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

由於某種原因它給了我一個錯誤「無法在類欄中找到屬性foo的setter」。我通過在getProductName()函數上面添加@Transient註解來解決它。並且在頂部的import javax.persistence.Transient中添加了這個; – MINDoSOFT

+0

+1,正確的解決方法。看起來,你有序列化/反序列化,在這種情況下,預計會得到一組get/set。 Transient註解將這個從序列化/反序列化範圍中排除。 –

-1

這是沒有必要改變你的常規的Java類:

(沒有需要修改的文件)

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

請僅用英語發表! – FelixSFD

+1

請用英語發帖! – Seb

+0

回答者文本的翻譯將是「不需要更改常規的Java類」 –