我目前正在用JavaFX和FXML编写程序。我当前的问题是我有一个FXMLTableView
,它应该显示两个不同对象类的特征,即Stockorder
和Article
,即商品的名称,标识和价格以及该商品有多少库存(在库存订单中定义)。我目前有以下代码:
库存订单:
public class Stockorder {
private SimpleStringProperty deliveryState;
private SimpleStringProperty stockOrderId;
private SimpleStringProperty orderdate;
private SimpleStringProperty deliverydate;
private SimpleStringProperty count;
private SimpleStringProperty itemId;
private SimpleStringProperty itemName;
public Stockorder(String deliveryState, String stockOrderId, String orderdate, String deliverydate, String count, String itemId, String itemName) {
this.deliveryState = new SimpleStringProperty(deliveryState);
this.stockOrderId = new SimpleStringProperty(stockOrderId);
this.orderdate = new SimpleStringProperty(orderdate);
this.deliverydate = new SimpleStringProperty(deliverydate);
this.count = new SimpleStringProperty(count);
this.itemId = new SimpleStringProperty(itemId);
this.itemName = new SimpleStringProperty(itemName);
}
public boolean getDeliveryState() {
return Boolean.valueOf(deliveryState.get());
}
public StringProperty getDeliveryStateProperty() {
return deliveryState;
}
public int getStockOrderId() {
return Integer.parseInt(stockOrderId.get());
}
public StringProperty getStockOrderIdProperty() {
return stockOrderId;
}
public String getOrderdate() {
return orderdate.get();
}
public StringProperty getOrderdateProperty() {
return orderdate;
}
public String getDeliverydate() {
return deliverydate.get();
}
public StringProperty getDeliverydateProperty() {
return deliverydate;
}
public int getCount() {
return Integer.parseInt(count.get());
}
public StringProperty getCountProperty() {
return count;
}
public int getItemId() {
return Integer.parseInt(itemId.get());
}
public StringProperty getItemIdProperty() {
return itemId;
}
public String getItemName() {
return itemName.get();
}
public StringProperty getItemNameProperty() {
return itemName;
}
}
文章:
public class Article {
private final SimpleStringProperty articleNr;
private final SimpleStringProperty name;
private final SimpleStringProperty price;
public Article(String articleNr, String name, String price) {
this.articleNr = new SimpleStringProperty(articleNr);
this.name = new SimpleStringProperty(name);
this.price = new SimpleStringProperty(price);
}
public int getArticleNr() {
return Integer.parseInt(articleNr.get());
}
public String getName() {
return name.get();
}
public double getPrice() {
return Double.parseDouble(price.get());
}
public StringProperty getArticleNrProperty(){
return articleNr;
}
public StringProperty getNameProperty(){
return name;
}
public StringProperty getPriceProperty(){
return price;
}
}
EditArticleOverviewControl(FXMLController)
public class EditArticlesOverviewController implements Initializable {
public EditArticlesOverviewController() {
System.out.println("EditArticleOverviewController started");
}
private ApplicationControl applicationControl;
private EditOrderController editOrderController = new EditOrderController();
private String stockOrderURL = "stockorders";
private HttpClient client = new HttpClient();
@FXML
TableView<Article> tableView;
@FXML
TableColumn<Article, String> articleNrColumn;
@FXML
TableColumn<Article, String> nameColumn;
@FXML
TableColumn<Article, String> priceColumn;
@FXML
TableColumn<Stockorder, String> stockColumn;
@FXML
TableColumn<Stockorder, String> minStockColumn;
@FXML
TableColumn<Stockorder, String> addColumn;
@FXML
Button cancelButton;
@Override
public void initialize(URL url, ResourceBundle rb) {
articleNrColumn.setCellValueFactory(cellData -> cellData.getValue().getArticleNrProperty());
nameColumn.setCellValueFactory(cellData -> cellData.getValue().getNameProperty());
priceColumn.setCellValueFactory(cellData -> cellData.getValue().getPriceProperty());
stockColumn.setCellValueFactory(cellData -> cellData.getValue().getCountProperty());
minStockColumn.setCellValueFactory(cellData -> cellData.getValue().getDeliveryStateProperty());
addColumn.setCellValueFactory(cellData -> cellData.getValue().getCountProperty());
}
public void setApplicationControl(ApplicationControl applicationControl) {
this.applicationControl = applicationControl;
}
public void setEntriesInTableView(ObservableList articlesList) {
tableView.setItems(articlesList);
}
@FXML
public void goBack() {
System.out.println("Kein Artikel bearbeitet");
Stage stage = (Stage) cancelButton.getScene().getWindow();
stage.close();
//EditOrder wieder starten vom selben Order wie vorher!!
try {
applicationControl.openEditOrder(applicationControl.order.getOrderNr());
} catch (Exception ex) {
Logger.getLogger(OrdersOverviewController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
现在,每次我尝试运行程序时,都会出现错误:
java.lang.ClassCastException: client.Article cannot be cast to client.Stockorder
在将
cellValueFactory
设置为stockOrder
的行。但是我不明白为什么,因为该列包含Stockorder
,而cellValueFactory
使用Stockorder
类的方法。 最佳答案
用你的代码
TableColumn<Stockorder, String> stockColumn;
这意味着
stockColumn
将尝试以Stockorder的形式获取商品。 TableColumn<S, T>
的S影响setCellValueFactory(Callback<TableColumn.CellDataFeatures<S,T>,ObservableValue<T>> value)
的S,并返回TableColumn.CellDataFeatures<S,T>::getValue()
的类型S。但是实际上,
TableView
中的项目不是Stockorder
的实例,因此ClassCastException
在运行时抛出。 TableView<S>
和TableColumn<S,T>
的所有S类型必须相同。在这种情况下,为了在
TableView
中显示它们,需要创建一个数据模型类以供使用。例如:class RowData {
private Stockorder stockorder;
private Article article;
public RowData(Arthicle article, Stockorder stockorder) {
this.article = article;
this.stockorder = stockorder;
}
public Stockorder getStockorder(){ return stockorder; }
public Article getArticle(){ return arthicle; }
}