JavaFx 自定义 ListCell 为空

JavaFx custom ListCell is empty

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

我正在使用 JDK 12 和基于 Maven JFX Archetype(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);
    }

}

}

Student.java

public class Student {
private String name;



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

}

}

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

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

您的 ListCell.fxml 文件没有将 fx:id 分配给您的 AnchorPane。因此,当您在 StudentListViewCell.java class 中定义它时,您实际上是在创建一个新的 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>