当您声明您的ListView 时,您应该真正指定您的对象模型,而不是您的情况下的节点 (TodoView)。
您可以定义您的布局以及您希望每个ListView 单元格在setCellFactory 方法中的外观。这使您可以更好地控制每个项目并遵循更适当的关注点分离(将数据模型与 UI 分开)。
我在这个例子中使用了书店的概念,但是您会发现它允许您完全控制每个单元格的布局:
守则:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ListViewCustomObjects extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// Create a simple layout
VBox root = new VBox(5);
root.setAlignment(Pos.TOP_CENTER);
root.setPadding(new Insets(5));
// Create a list of Books
ObservableList<Book> booksList = FXCollections.observableArrayList();
booksList.addAll(
new Book("Where the Red Fern Grows", new Image("Controls/ListView/img/fern.jpg")),
new Book("Hatchet", new Image("Controls/ListView/img/hatchet.jpg")),
new Book("David Copperfield", new Image("Controls/ListView/img/david_copperfield.jpg"))
);
// Create our ListView
ListView<Book> bookListView = new ListView<>();
bookListView.setItems(booksList);
// Here we'll create our ListView's CellFactory, which will control how each Book item is displayed.
bookListView.setCellFactory(cell -> {
return new ListCell<Book>() {
// Let's create the HBox layout and elements that will be displayed. The actual values will be
// updated in the updateItem() method.
final HBox rootLayout = new HBox(5) {{
setAlignment(Pos.CENTER_LEFT);
setPadding(new Insets(5));
}};
// The ImageView for the Book's cover art
final ImageView cover = new ImageView() {{
}};
// Create the Label that will hold the book's title
final Label title = new Label();
// The Button we'll include to order the book
final Button orderButton = new Button("Order Now");
// This static block allows us to add our elements to the HBox outside of the updateItem() method.
// We'll add the book's cover
{
rootLayout.getChildren().addAll(cover, title, orderButton);
}
@Override
protected void updateItem(Book item, boolean empty) {
super.updateItem(item, empty);
if (item != null) {
// This is where we update our rootLayout HBox to display this specific Book
cover.setImage(item.getCover());
// Let's just set our image size here
cover.setPreserveRatio(true);
cover.setFitWidth(50);
cover.setFitHeight(100);
title.setText(item.getTitle());
// Simple onAction() method to print out the book we're purchasing.
orderButton.setOnAction(event -> {
System.out.println("Ordering \"" + item.getTitle() + "\"!");
});
// Finally, set this cell's graphic to display the HBox
setGraphic(rootLayout);
} else {
// Not book in this cell, set the graphic to null
setGraphic(null);
}
}
};
});
// Finally, add our ListView to the root VBox
root.getChildren().add(bookListView);
// Build and show the Scene
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
}
// Sample data model. For this example, we'll be displaying a list of Books
class Book {
// Each book will have a title and cover image.
private final String title;
private final Image cover;
public Book(String title, Image cover) {
this.title = title;
this.cover = cover;
}
public String getTitle() {
return title;
}
public Image getCover() {
return cover;
}
}