javaFx Listview中的图像仅在选中时显示

javaFx Listview中的图像仅在选中时显示,java,image,listview,javafx,Java,Image,Listview,Javafx,我想制作一个包含图像、一些文本和按钮专业栏的列表视图,但图像仅在选择(单击)栏时显示。但我希望图像/图标的显示与选择/点击无关 todoView.setCellFactory(new Callback<ListView<TodoView>, ListCell<TodoView>>() { @Override public ListCell<TodoView> call(ListView<TodoView>

我想制作一个包含图像、一些文本和按钮专业栏的列表视图,但图像仅在选择(单击)栏时显示。但我希望图像/图标的显示与选择/点击无关

todoView.setCellFactory(new Callback<ListView<TodoView>, ListCell<TodoView>>() {
        @Override
        public ListCell<TodoView> call(ListView<TodoView> todoViewListView) {
           ListCell<TodoView> cell = new ListCell<>() {
               @Override
               protected void updateItem(TodoView item, boolean empty) {
                   super.updateItem(item, empty);
                   if (item != null) {
                       setGraphic(item);
                   }
               }
           };
            return cell;
        }
    });
todoView.setCellFactory(新回调(){
@凌驾
公共ListCell调用(ListView到提供ListView){
ListCell=新ListCell(){
@凌驾
受保护的void updateItem(TodoView项,布尔值为空){
super.updateItem(项,空);
如果(项!=null){
设置图形(项目);
}
}
};
返回单元;
}
});
(TodoView)项目obj是一个带有图像视图、标签和按钮的hbox。。。
有什么想法吗?

当你声明你的
列表视图时,你真的应该指定你的对象模型,而不是在你的案例中指定一个节点(
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;
    }
}
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.Label;
导入javafx.scene.control.ListCell;
导入javafx.scene.control.ListView;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类ListViewCustomObjects扩展了应用程序{
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
//创建一个简单的布局
VBox根=新的VBox(5);
根部设置对齐(位置顶部\中心);
根。设置填充(新插图(5));
//创建一个图书列表
ObservableList booksList=FXCollections.observableArrayList();
booksList.addAll(
新书(“红色蕨类植物生长的地方”,新图片(“Controls/ListView/img/Fern.jpg”),
新书(“Hatchet”,新图片(“Controls/ListView/img/Hatchet.jpg”),
新书(“David Copperfield”,新图片(“Controls/ListView/img/David_Copperfield.jpg”))
);
//创建我们的ListView
ListView bookListView=新建ListView();
bookListView.setItems(booksList);
//在这里,我们将创建ListView的CellFactory,它将控制每个图书项目的显示方式。
bookListView.setCellFactory(单元格->{
返回新的ListCell(){
//让我们创建将要显示的HBox布局和元素。实际值将为
//在updateItem()方法中更新。
最终HBox根布局=新HBox(5){{
设置对齐(位置中心左);
设置填充(新插图(5));
}};
//本书封面艺术的ImageView
最终ImageView封面=新ImageView(){{
}};
//创建用于保存书名的标签
最终标签标题=新标签();
//我们订购这本书的按钮
最终按钮订单按钮=新按钮(“立即订单”);
//这个静态块允许我们在updateItem()方法之外将元素添加到HBox。
//我们将增加这本书的封面
{
rootLayout.getChildren().addAll(封面、标题、订单按钮);
}
@凌驾
受保护的void updateItem(书籍项,布尔值为空){
super.updateItem(项,空);
如果(项!=null){
//这就是我们更新rootLayout HBox以显示这本特定书籍的地方
setImage(item.getCover());
//让我们在这里设置图像大小
覆盖率(真实);
覆盖件。设置宽度(50);
盖。安装高度(100);
title.setText(item.getTitle());
//简单的onAction()方法打印出我们正在购买的书。
orderButton.setOnAction(事件->{
System.out.println(“Ordering\”+item.getTitle()+“\”!”;
});
//最后,设置此单元格的图形以显示HBox
setGraphic(rootLayout);
}否则{
//此单元格中没有书本,请将图形设置为空
设置图形(空);
}
}
};
});
//最后,将ListView添加到根VBox
root.getChildren().add(bookListView);
//构建并显示场景
场景=新场景(根);
初级阶段。场景(场景);
primaryStage.show();
}
}
//样本数据模型。在本例中,我们将显示一个书籍列表
课堂用书{
//每本书将有一个标题和封面图像。
私人最终字符串标题;
私人最终图像封面;
公共书籍(字符串标题、图像封面){
this.title=标题;
this.cover=cover;
}
公共字符串getTitle(){
返回标题;
}
公共图像获取封面(){