I've been having an issue creating a custom cell for list view in JavaFX. In short, I have an observable list of objects (of type BillItem) to create a custom fxml view and add it to the list view.
In the list view, I have just a ListView as the root.
<ListView fx:id="bill" prefWidth="200.0" style="-fx-background-color: yellow;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="restroid.controllers.left.BillViewController"/>
In the cell view, I have BorderPane in the root and 3 other labels.
<BorderPane fx:id="billItem" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="restroid.controllers.left.BillItemViewController">
<left>
<Label fx:id="numberOfItems" text="2" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets right="10.0"/>
</BorderPane.margin>
</Label>
</left>
<center>
<Label fx:id="itemName" text="Item name" BorderPane.alignment="TOP_LEFT"/>
</center>
<right>
<Label fx:id="price" text="56.00 TL" BorderPane.alignment="CENTER"/>
</right>
</BorderPane>
When I load the fxml file for the list view, I set up some dummy data in the initialize() method of the responsible controller and set it on the bill (ListView) with setItems(). Finally, using the cell factory, I return a custom ListCell of type BillItem.
@Override
public void initialize(URL location, ResourceBundle resources) {
for (int i = 0; i < 10; i++)
billItems.add(new BillItem(2, "Item name", 56.00));
observableList = FXCollections.observableList(billItems);
bill.setItems(observableList);
bill.setCellFactory(param -> new BillItemCell());
}
In the updateItem() of the BillItemCell class, I found out that "item" is null and I immediately get the following Exception. There must have been a problem about how I initialize the observable list, though I followed the code examples similar to what I have here.
@Override
protected void updateItem(BillItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null) {
BillItemViewController cell = new BillItemViewController();
cell.setNumberOfItems(item.getNumberOfItems());
cell.setItemName(item.getItemName());
cell.setPrice(item.getPrice());
setGraphic(cell.getBillItem());
} else {
System.out.println("item is null");
}
}
Exception in Application start method
Exception in thread "main" java.lang.NoSuchMethodException: restroid.MainApp.main([Ljava.lang.String;)
at java.lang.Class.getMethod(Class.java:1786)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:125)
My first question is, why couldn't the program pass my observable list to the factory?
My other question is about how I'm going to load the custom view to the list view since I never got the chance to test this code because of this issue. I did some digging around and came up with the implementation above. In the BillItemViewController, I'm just loading the custom view and provide the necessary setters.
public BillItemViewController() {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("../../views/left/BillItemView.fxml"));
try {
fxmlLoader.setController(this);
fxmlLoader.load();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Is this a right approach or am I missing something?