我正在尝试为JavaFX ListCell创建一个非常简单的自定义Listview。运行应用程序时,ListView中的项目没有任何内容。它们是可单击的,但为空。如下图所示:

java - JavaFx自定义ListCell为空-LMLPHP

我正在使用JDK 12和基于Maven JFX原型(archetype-artifactid:javafx-archetype-fxml,groupid:org.openjfx)的设置。我遵循了一个名为“ 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);
    }

}


}

学生.java

public class Student {
private String name;



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

}


}

我希望一个ListCell中间有一个标签,上面写着“ rightText”。但是似乎我的自定义列表单元甚至没有呈现。有什么建议么?

最佳答案

除了您的实现看起来比需要的复杂得多之外,您的实际问题还很简单。

您的ListCell.fxml文件没有为您的fx:id分配AnchorPane。因此,在StudentListViewCell.java类中定义它时,实际上是在创建一个新的AnchorPane,并且其中一个不包含Label

只需更改您的ListCell.fxml文件并分配ID,即可解决该问题:

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

09-05 15:05