ListView中细胞的怪异循环 - 的JavaFX [英] Weird recycle of cells in ListView - JavaFX

查看:158
本文介绍了ListView中细胞的怪异循环 - 的JavaFX的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从JavaFX的的文件理解的是,当有足够数量的细胞,以填补在ListView的规定区域(或者类似),产生新的细胞。否则,现有的细胞被再利用,通过调用的updateItem方法上各有相应的项目。

What I understand from the documentation of JavaFX is that, when there are insufficient number of cells to fill the provided area of the ListView (or else like), new cells are generated. Otherwise, existing cells are reused, by calling updateItem method on each with the corresponding items.

我实现一个聊天应用程序,用户在其中写一些东西到textarea的,presses进入和聊天追加到文本区,非常简单和安培以上的历史;经典。历史是一个ListView,显示发送聊天列表/接收为止。因此,当用户presses进入,我想补充到底层观察的名单一个新的项目,所以它在ListView显示出来。

I am implementing a chat application, in which the user writes something to the textarea, presses enter and the chat is appended to the history above the text area, very simple&classic. The history is a ListView, showing list of chats sent/received so far. So when the user presses enter, I add a new item to the underlying observable list, so it shows up in the ListView.

的问题是,当一个新的聊天被附加到ListView,有某种列表中的一个闪烁的,这需要一些时间来更新列表中的项目。 然而,新添加的聊天是在列表的末尾,这是不可见的用户(需要向下滚动,现在是)。所以实际上它并不需要更新已可见单元格,但它确实。我试图简化的updateItem方法的内容,但是没办法......它总是闪烁。

The problem is, when a new chat is appended to the ListView, there is some kind of a blink in the list, it takes a little time to update the items in the list. However, the newly added chat is at the end of the list, and it is not visible to the user (needs to scroll down, for now). So actually it is not needed to update the already visible cells, but it does. I tried to simplify the content of the updateItem method, but no way... It is always blinking.

然后,我实现了一个简单的类等;

Then I implemented a simple class like;

public class IdGenerator {
    private static IdGenerator instance = new IdGenerator();
    private int id = 0;

    public static IdGenerator getInstance() {
        return instance;
    }

    public synchronized int getId() {
        return ++id;
    }
}

和然后通过分配的标识,以生成细胞;

and then assigned ids to the generated cells by;

public class CommunicationEntityCell extends ListCell<CommunicationEntity> {

    ...
    private int id = IdGenerator.getInstance().getId();
    ....

    @Override
    protected synchronized void updateItem(CommunicationEntity entity, boolean empty) {
        super.updateItem(entity, empty);
        System.out.println(id);
        ....
    }
}

和我观察到,当一个新项目被添加到基础列表,细胞的复制,不回收。 (也许这是眨眼的原因,反正)

And I observed that, when a new item is added to the underlying list, the cells are reproduced, not recycled. (And probably this is reason of that blink, anyway)

这是正常/逻辑/预计要被再现的细胞?这是一个(已知)的错误?你见过吗?任何解决办法将是非常美联社preciated。

Is it normal/logical/expected for cells to be reproduced? Is this a (known) bug? Have you ever seen this? Any workaround would be highly appreciated.

推荐答案

我创建了一个类似的试验:

I created a similar test:

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ListCellReuseTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        final BorderPane root = new BorderPane();
        final ListView<String> list = new ListView<>();
        final Button addButton = new Button("Add message");
        addButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                int count = list.getItems().size() + 1 ;
                System.out.println("Creating message "+count);
                list.getItems().add("Message "+count);
            }
        });
        list.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {

            @Override
            public ListCell<String> call(ListView<String> listView) {
                return new TestListCell();
            }

        });

        root.setCenter(list);
        root.setBottom(addButton);
        primaryStage.setScene(new Scene(root, 200, 400));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    public static class TestListCell extends ListCell<String> {
        private static int nextId ;
        private final int id ;
        public TestListCell() {
            id = ++nextId ;
        }
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            setText(item);
            System.out.println(id);
        }

    }

}

在JavaFX 2.2,这似乎创造ListCells数量庞大的(我每次preSS的按钮时,17个新细胞,有16个细胞可见),并调用的updateItem(...)更多倍。我想,许多这些细胞的走出去的范围相当迅速,而且垃圾收集。

In JavaFX 2.2 this seems to create an enormous number of ListCells (17 new cells every time I press the button; there are 16 cells visible) and calls updateItem(...) even more times. I guess that many of these cells go out of scope fairly quickly and are garbage collected.

的JavaFX 8所示完全不同的行为下运行同一code;它创建的第一个按钮preSS 17细胞,然后创建后,没有新的。有到的updateItem少得多的呼叫(...),并且当不显示新的小区无。这似乎是它应该是更高效,肯定是更直观,更符合我期望的那样密切。

Running the same code under JavaFX 8 shows quite different behavior; it creates 17 cells on the first button press and then creates no new ones after that. There are far fewer calls to updateItem(...), and none when the new cell is not displayed. This seems like it should be more efficient and is certainly more intuitive and closer in line with what I'd expect.

我看不到任何的闪烁你的报告,不过,无论是在JavaFX的2.2或JavaFX的8;所以它不是立即清楚,这直接关系到电池的创建和重新使用的行为。这可能是你的updateItem的其余部分(...)方法可以更有效率(例如缓存复杂的图形,而不是每次都重新创建它们),或者还有别的东西发生,是造成这一点。

I do not see any of the "blinking" you report, though, either under JavaFX 2.2 or JavaFX 8; so it's not immediately clear that this is directly related to the cell creation and reuse behavior. It may be that the remainder of your updateItem(...) method can be made more efficient (e.g. cache complex graphics instead of recreating them each time), or that there is something else happening that is causing this.

你看到的JavaFX 8下,同样的事情?

Do you see the same thing under JavaFX 8?

这篇关于ListView中细胞的怪异循环 - 的JavaFX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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