当前位置: 首页 > 知识库问答 >
问题:

带有自定义对象的JavaFX自定义单元格工厂

危寒
2023-03-14

我正在尝试使用基于自定义对象列表的自定义单元格创建一个自定义ListView

自定义对象是名为message的类名,其中包含一些用于消息内容、收件人、时间戳和状态(读取、发送等)的字段。

在看了这个问题:用FXML在JavaFX中定制ListView之后,我成功地做到了:

    null
final ObservableList observableList = FXCollections.observableArrayList();
observableList.setAll(myMessages); //assume myMessage is a ArrayList<Message>
conversation.setItems(observableList); //the listview
conversation.setCellFactory(new Callback<ListView<Message>, ListCell<Message>>() {
    @Override
    public ConversationCell<Message> call(ListView<Message> listView) {
        return new ConversationCell();
    }
});

现在,ConversationCell类:

public final class ConversationCell<Message> extends ListCell<Message> { 

    @Override
    protected void updateItem(Message item, boolean empty) {
        super.updateItem(item, empty);
        ConversationCellController ccc = new ConversationCellController(null);
        setGraphic(ccc.getView());
    }
}

我不能显示ConversationCellController,但我所能说的是,这是我(在其构造函数中)加载设计单元格的FXML文件的地方,然后我可以用给定的消息项填充值。

getview()方法返回包含现在填充和设计的单元格的根窗格。

共有1个答案

曾光誉
2023-03-14

重写updateItem(...)的所有自定义单元格实现都需要处理该方法中单元格为空的情况。所以你可以用

public final class ConversationCell<Message> extends ListCell<Message> { 

    @Override
    protected void updateItem(Message item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setGraphic(null);
        } else {
            // did you mean to pass null here, or item??
            ConversationCellController ccc = new ConversationCellController(null);
            setGraphic(ccc.getView());
        }
    }
}

然而,从性能的角度来看,这并不是一个好的解决方案。每次使用非空单元格调用updateItem(...)时,都要加载FXML,这是一个相当昂贵的操作(可能涉及文件I/O、从jar文件解压缩FXML文件、解析文件、大量反射、创建新的UI元素等)。您不希望每次用户将列表视图滚动几个像素时,都要求FX应用程序线程完成所有这些工作。相反,您的单元格应该缓存节点,并在updateItem方法中更新它:

public final class ConversationCell<Message> extends ListCell<Message> { 

    private final ConversationCellController ccc = new ConversationCellController(null);
    private final Node view = ccc.getView();

    @Override
    protected void updateItem(Message item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setGraphic(null);
        } else {
            ccc.setItem(item);
            setGraphic(view);
        }
    }
}

您应该在ConversationCellController中定义一个SetItem(...)方法,该方法相应地更新视图(在标签上设置文本等)。

 类似资料:
  • 我有一个显示对象列表的组合框。我已经为组合框编写了一个自定义单元格工厂: ListView显示了一个字符串(id名称),但当我从ListView中选择一个项目时,Combobox显示了toString()方法的返回值,即对象的地址。我无法重写toString()方法,因为User域对象应该与服务器上的对象相同。如何在组合框中显示id?请建议 编辑1 我尝试了下面的代码。现在,当我从列表视图中选择一

  • 我想将 UI 表视图与不同的自定义表视图单元一起使用。我的3个单元格是这样的: Cell1:应该有一个图像和一个标签。 Cell2:应该有两个标签。 Cell3:应该有一天选择器。 我不想为单元格编写标签代码。我如何在Swift中管理这些?我必须为每个单元格编写自己的类吗?我可以使用一个tableviewController吗?如何在不同的单元格中填充数据? 我想生成一个表视图,就像iOS设备的联

  • 我尝试用自定义控制器制作一个自定义组件。自定义组件已经显示在应用程序上,但我未能向其添加属性。 项目结构: null 布尔马尔科 完全错误: 原因:java.lang.nullPointerException:无法调用“javafx.scene.image.imageeview.setimage(javafx.scene.image.image)”,因为“controller.topbarbtn.

  • 第一次使用JavaFX,所以我对/方法有一个问题。我在做一个弹跳球项目。首先,我使用对象创建球,但由于需要传递更多参数,我决定构建自己的球类()。这是我以前使用时使用的代码: 当将和和放入中时,就会使“球”弹出墙壁。现在,我正试图弄清楚如何使用ball来实现这一点,因为在使用我自己的对象时,无法解析、和方法。如何处理这个/构建自己的等?

  • 我的代码中有以下扩展的JavaFX对象: 它使用我编写的这个客户Java类来跟踪Tile位置: 现在,我想构建一个场景(通过JavaFX场景生成器),它使用一个网格窗格,每个单元格中都有一个平铺对象。我决定首先在scene Builder中构建一个场景,使用JavaFX矩形对象而不是平铺,然后手动编辑.fxml文件并将其中的矩形更改为平铺对象。问题是Intellij现在告诉我FXML文件中的平铺对