2017-05-06 4 views
0

Ich schreibe gerade ein Programm mit JavaFX und FXML. Mein derzeitiges Problem ist, dass ich eine FXMLTableView habe, die Eigenschaften von zwei verschiedenen Objektklassen, Stockorder und Article anzeigen sollte, nämlich den Namen, die ID und den Preis des Artikels und wie viele Artikel auf Lager sind (die im Lagerbestand definiert ist)). Im Moment habe ich den folgenden Code:JavaFX Tableview mit zwei Arten von Objekten

Stockorder:

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; 
    } 
} 

Artikel:

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

Nun jedes Mal, wenn ich versuche, das Programm laufen zu lassen, Ich erhalte den Fehler:

java.lang.ClassCastException: client.Article cannot be cast to client.Stockorder 

an der Linie, wo ich die cellValueFactory für stockOrder gesetzt. Aber ich kann nicht verstehen, warum, wie die Spalte Stockorder und die cellValueFactory verwendet Methoden der Stockorder Klasse hält.

+0

können Sie die Zeile? –

+0

stockColumn.setCellValueFactory (cellData -> cellData.getValue(). GetCountProperty()); Dieser. Die vierte 'setCellValueFactory' in der ** EditArticlesOverviewController * Class –

Antwort

0

Auf Ihren Code,

TableColumn<Stockorder, String> stockColumn; 

Es bedeutet stockColumn wird versuchen, Elementeals Stockorder zu bekommen. Das S von TableColumn<S, T> betrifft S von setCellValueFactory(Callback<TableColumn.CellDataFeatures<S,T>,ObservableValue<T>> value) und den Rückgabetyp S von TableColumn.CellDataFeatures<S,T>::getValue().

Aber tatsächlich, Elemente in der TableView ist keine Instanz von Stockorder, so ClassCastException wird zur Laufzeit geworfen. Alle S-Typen von TableView<S> und TableColumn<S,T> müssen identisch sein.

In diesem Fall müssen Sie, um sie in einer TableView anzuzeigen, eine Datenmodellklasse erstellen, um sie zu verwenden. Zum Beispiel:

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

Und dann wäre die der TableView und alle TableColumns RowData? Und die Methode wäre '[...] -> cellData.getValue(). GetStockorder(). GetCountProperty());'? –

+0

Das stimmt :) – monolith52

+0

Ok, vielen Dank! Ich werde wahrscheinlich versuchen, zwei TableViews als einen ersten Versuch in die FXML zu quetschen, da es eine Menge anderer Dinge gibt, die ich ändern müsste, um diese RowData-Klasse funktionieren zu lassen, da diese Klasse nur ein kleines Stück von einem größeren ist Projekt :) –