简体   繁体   English

Javafx ListView动态更新

[英]Javafx ListView update dynamically

I am creating a Chat application with JavaFx. 我正在用JavaFx创建一个聊天应用程序。 My friend list is loaded into a ListView. 我的朋友列表已加载到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. 由于我是FX的新手,因此我无法找到一种执行此操作的方法。 Any help would be appreciated. 任何帮助,将不胜感激。

在此处输入图片说明 Thank you 谢谢

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

    ...

}

or an external data structure like ObservableMap as used in the following example: 或以下示例中使用的外部数据结构(如ObservableMap

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. 对于存储在Friend类中的消息计数,您需要修改注册侦听器并稍微更新单元格。

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM