【问题标题】:JavaFx custom ListCell is emptyJavaFx 自定义 ListCell 为空
【发布时间】:2020-01-15 07:41:40
【问题描述】:

我正在尝试为 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);
    }

}

}

学生.java

public class Student {
private String name;



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

}

}

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

【问题讨论】:

  • 尝试在 FXML 文件中为您的 anchorPane 提供一个 ID,然后在您的字段 @FXML 上提供相同的 ID
  • @HassamAbdelillah 简单的事情让你“哦”。终于成功了,非常感谢
  • 这对于 ListCell 实现来说是很多不必要的开销。 ListCell 已经扩展了 Labeled,因此它有自己的 text 属性。不需要新的 AnchorPane 和 Label。而不是使用这些,只需致电this.setText("rightText");
  • 感谢 VGR 的建议。我在官方的 javadoc 中读过这个。我只是在里面放了一个标签来模拟一个自定义元素。这仅用于测试目的,以将问题分解为裸露的骨头。只是为了澄清,如果其他人读到这个,他们只想要文本,他们应该听从你的建议 =)

标签: java listview javafx fxml


【解决方案1】:

除了你的实现看起来比它需要的复杂得多之外,你的实际问题是一个非常简单的问题。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 2016-06-29
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多