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