JavaFx custom ListCell is empty

Flipper :

I'm trying to create a very simple custom ListCell for a JavaFX Listview. When running the Application there are Items in the ListView without any content. They're clickable but empty. Like following image shows:

enter image description here

I'm using JDK 12 and a Maven JFX Archetype(archetype-artifactid:javafx-archetype-fxml, groupid:org.openjfx) based setup. I followed a guide called "Turais Custom ListCell".

App.java

public class App extends Application {

private static Scene scene;

@Override
public void start(Stage stage) throws IOException {
    scene = new Scene(loadFXML("primary"));
    stage.setScene(scene);
    stage.show();
}

static void setRoot(String fxml) throws IOException {
    scene.setRoot(loadFXML(fxml));
}

private static Parent loadFXML(String fxml) throws IOException {
    FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
    return fxmlLoader.load();
}

public static void main(String[] args) {
    launch();
}

}

PrimaryController.java

public class PrimaryController implements Initializable {

ObservableList<Student> students;

@FXML
private ListView<Student> listView1;

@FXML
private void switchToSecondary() throws IOException {
    App.setRoot("secondary");
}

public PrimaryController(){
    super();
    students = FXCollections.observableArrayList();
   students.add(new Student());

}

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    listView1.setItems(students);
    listView1.setCellFactory(new Callback<ListView<Student>, ListCell<Student>>() {
        @Override
        public ListCell<Student> call(ListView<Student> listView) {
            return new StudentListViewCell();
        }
    });
}

}

Primary.fxml

<VBox alignment="CENTER" prefHeight="257.0" prefWidth="230.0" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.test.PrimaryController">    
   <children>
      <Label text="Primary View" />
      <Button fx:id="primaryButton" onAction="#switchToSecondary" text="Switch to Secondary View" />    
      <ListView fx:id="listView1" prefHeight="200.0" prefWidth="200.0" />
   </children>
   <padding>
      <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
   </padding>
   </VBox>    

ListCell.fxml

<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label  fx:id="label1" layoutX="293.0" layoutY="190.0" text="Label" />
   </children>
</AnchorPane>    

StudentListViewCell.java

public class StudentListViewCell extends ListCell<Student> {

@FXML
private Label label1;

@FXML
private AnchorPane anchorPane;

private FXMLLoader mLLoader;

@Override
protected void updateItem(Student student, boolean empty) {
    super.updateItem(student, empty);

    if(empty || student == null) {

        setText(null);
        setGraphic(null);

    } else {
        if (mLLoader == null) {
            mLLoader = new FXMLLoader(getClass().getResource("ListCell.fxml"));
            mLLoader.setController(this);

            try {
                mLLoader.load();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        label1.setText("rightText");


        setText(null);
        setGraphic(anchorPane);
    }

}

}

Student.java

public class Student {
private String name;



public Student(String name){
    this.name = name;

}

}

I'd expect a single ListCell which has a label in the middle with "rightText" written in it. But it seems like my custom listcell is not even rendered. Any suggestions?

Zephyr :

Aside from your implementation appearing to be much more complex than it needs to be, your actual issue is a very simple one.

Your ListCell.fxml file does not assign an fx:id to your AnchorPane. Therefore, when you define it in your StudentListViewCell.java class, you're essentially creating a new AnchorPane, and one that does not contain your Label.

Simply changing your ListCell.fxml file and assigning the id will fix that issue:

<AnchorPane fx:id="anchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.172-ea"
            xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <Label fx:id="label1" layoutX="293.0" layoutY="190.0" text="Label"/>
    </children>
</AnchorPane>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=165911&siteId=1