JavaFX的自定义单元格工厂自定义对象 [英] JavaFX custom cell factory with custom Objects

查看:1179
本文介绍了JavaFX的自定义单元格工厂自定义对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有一个自定义的的ListView 制作自定义的细胞基于自定义列表<$ C上$ C>对象。

I am trying to have a custom ListView made of custom Cell based on a list of custom objects.

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

The custom object is class name called Message which contains a few fields for the message content, recipient, timestamp and status (read, sent etc.).

在看这个问题后:自定义的ListView JavaFX中与FXML 我已经成功:

After looking at this question : Customize ListView in JavaFX with FXML I have successfully :


  1. 创建了自定义细胞其中单元设计在 FXML文件中定义一个ListView;

  2. 相关联的控制器,以便每个单元格数据可以充满集合的当前项目;

  1. created a ListView with custom cells where the cell design is defined in a FXML file ;
  2. associated a controller so that each cell data can be filled with the current item of the collection ;

不过,我没能同时连结:我似乎无法找到一种方法,使ListView控件的当前项被发送的单元控制器

However, I failed to link both : I cannot seem to find a way so that the current item of the ListView is sent the Cell Controller.

下面是我的code的细胞工厂和项目的ListView填充:

Here is my code for the cell factory and the ListView filling of items:

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类:

And now, the ConversationCell class :

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文件,然后我可以填补与给定的信息项的值。

I cannot show the ConversationCellController but all I can say, this is where (in its constructor) I load the FXML file that designs the cell and then I can fill the values with the given Message item.

getView()方法返回一个包含了现在填充和设计的电池。在根窗格

The getView() method returns the root pane that contains the now-filled-and-designed cell.

当我previously说,设计工作,但我似乎无法ListView的项目进行链接的 CellFactory 因为在法

As I previously say, the designing work, but I cannot seem to link the ListView items with the CellFactory because in method

保护无效的updateItem(消息项目,布尔空)

protected void updateItem(Message item, boolean empty)

设置为真正并产品确实

我能做些什么,使这项工作?

What can I do to make this work ?

推荐答案

所有的自定义单元格实现了覆盖的updateItem(...)需要处理的情况下细胞是在该方法是空的。所以,你可以做这样一个天真的修复与

All custom cell implementations that override updateItem(...) need to deal with the case where the cell is empty in that method. So you could do a naïve fix of this with

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());
        }
    }
}

然而,这不是从视图的性能的点一个好的解决办法。您每次加载FXML 的updateItem(...)是带一个非空单元格,这是一个pretty昂贵的操作(可能涉及文件I / 0,解压缩从一个jar文件中FXML文件,分析文件,大量反射,创造新的UI元素等)。你不希望被询问FX应用程序线程将尽一切努力,每次用户滚动几个像素列表视图。相反,你的电池应该缓存节点,应在的updateItem 方法更新:

However, this is not a good solution from the point of view of performance. You are loading the FXML every time updateItem(...) is called with a non-empty cell, and that's a pretty expensive operation (potentially involving file i/o, unzipping the FXML file from a jar file, parsing the file, lots of reflection, creating new UI elements, etc). You don't want to be asking the FX Application Thread to be doing all that work every time the user scrolls the list view by a few pixels. Instead, your cell should cache the node and should update it in the updateItem method:

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(...)方法在标签,等等等等)相应。

You should define a setItem(...) method in the ConversationCellController that updates the view (sets text on labels, etc etc) accordingly.

这篇关于JavaFX的自定义单元格工厂自定义对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆