Javafx ListView动态更新 [英] Javafx ListView update dynamically

查看:812
本文介绍了Javafx ListView动态更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JavaFx创建一个Chat应用程序。我的好友列表被加载到ListView中。我的要求是当用户收到朋友的消息时显示通知图标。为此,我需要知道朋友所在的单元格,并且还需要显示通知图标。我无法找到一种方法来做到这一点;我对FX非常新。
任何帮助都将不胜感激。

I am creating a Chat application with JavaFx. My friend list is loaded into a ListView. My requirement is to show a notification icon when the user receives a message from a friend. For that I need to know the cell in which the friend is and also I need to show the notification icon. I cannot figure out a way to do this as I;m very new to FX. Any help would be appreciated.


谢谢

推荐答案

在一些可观察的信息中存储有关您收到通知的朋友的信息。这可能是项目类本身

Store the info about the friends you are notified about in some observable. This could be the item class itself

public class Friend {

    private final IntegerProperty messageCount = new SimpleIntegerProperty();

    public int getMessageCount() {
        return messageCount.get();
    }

    public void setMessageCount(int value) {
        messageCount.set(value);
    }

    public IntegerProperty messageCountProperty() {
        return messageCount;
    }

    ...

}

或外部数据结构,如 ObservableMap ,如以下示例所示:

or an external data structure like ObservableMap as used in the following example:

public class Friend {

    private final String name;

    public String getName() {
        return name;
    }

    public Friend(String name) {
        this.name = name;
    }

}





@Override
public void start(Stage primaryStage) {
    // map storing the message counts by friend
    final ObservableMap<Friend, Integer> messageCount = FXCollections.observableHashMap();

    ListView<Friend> friendsListView = new ListView<>();
    friendsListView.setCellFactory(lv -> new ListCell<Friend>() {
        final StackPane messageNotification;
        final Text numberText;
        final InvalidationListener listener;

        {
            // notification item (white number on red circle)
            Circle background = new Circle(10, Color.RED);

            numberText = new Text();
            numberText.setFill(Color.WHITE);

            messageNotification = new StackPane(background, numberText);
            messageNotification.setVisible(false);

            listener = o -> updateMessageCount();
            setGraphic(messageNotification);
        }

        void updateMessageCount() {
            updateMessageCount(messageCount.getOrDefault(getItem(), 0));
        }

        void updateMessageCount(int count) {
            boolean messagesPresent = count > 0;
            if (messagesPresent) {
                numberText.setText(Integer.toString(count));
            }
            messageNotification.setVisible(messagesPresent);

        }

        @Override
        protected void updateItem(Friend item, boolean empty) {
            boolean wasEmpty = isEmpty();
            super.updateItem(item, empty);
            if (wasEmpty != empty) {
                if (empty) {
                    messageCount.removeListener(listener);
                } else {
                    messageCount.addListener(listener);
                }
            }

            if (empty || item == null) {
                setText("");
                updateMessageCount(0);
            } else {
                setText(item.getName());
                updateMessageCount();
            }

        }

    });

    Random random = new Random();
    List<Friend> friends = Stream
            .of(
                    "Sheldon",
                    "Amy",
                    "Howard",
                    "Bernadette",
                    "Lennard",
                    "Penny")
            .map(Friend::new)
            .collect(Collectors.toCollection(ArrayList::new));

    friendsListView.getItems().addAll(friends);

    List<Friend> messages = new ArrayList(friends.size() * 2);

    // 2 messages for each friend in random order
    Collections.shuffle(friends, random);
    messages.addAll(friends);
    Collections.shuffle(friends, random);
    messages.addAll(friends);

    // demonstrate adding/removing messages via timelines
    Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), new EventHandler<ActionEvent>() {

        Iterator<Friend> iterator = messages.iterator();

        @Override
        public void handle(ActionEvent event) {
            messageCount.merge(iterator.next(), 1, Integer::sum);
        }

    }));
    timeline.setCycleCount(messages.size());

    Timeline removeTimeline = new Timeline(new KeyFrame(Duration.seconds(1), new EventHandler<ActionEvent>() {

        Iterator<Friend> iterator = messages.iterator();

        @Override
        public void handle(ActionEvent event) {
            messageCount.merge(iterator.next(), 1, (a, b) -> a - b);
        }

    }));
    removeTimeline.setCycleCount(messages.size());

    new SequentialTransition(timeline, removeTimeline).play();

    Scene scene = new Scene(friendsListView);

    primaryStage.setScene(scene);
    primaryStage.show();
}

对于存储在朋友类你需要修改注册监听器和更新单元格。

For message counts stored in the Friend class you'd need to modify registering the listener and updating the cell a bit.

listener = o -> updateMessageCount(getItem().getMessageCount());





@Override
protected void updateItem(Friend item, boolean empty) {
    Friend oldItem = getItem();
    if (oldItem != null) {
        oldItem.messageCountProperty().removeListener(listener);
    }

    super.updateItem(item, empty);

    if (empty || item == null) {
        setText("");
        updateMessageCount(0);
    } else {
        setText(item.getName());
        item.messageCountProperty().addListener(listener);
        updateMessageCount(item.getMessageCount());
    }

}

这篇关于Javafx ListView动态更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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