Javafx ListView动态更新

时间:2018-08-09 10:51:16

标签: java javafx fxml

我正在使用JavaFx创建聊天应用程序。我的朋友列表已加载到ListView中。我的要求是当用户收到朋友的消息时显示通知图标。为此,我需要知道朋友所在的单元格,并且还需要显示通知图标。由于我是FX的新手,因此我无法找到一种执行此操作的方法。 任何帮助将不胜感激。

enter image description here 谢谢

1 个答案:

答案 0 :(得分:1)

以某种可观察的方式存储有关您收到通知的朋友的信息。这可能是商品类本身

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

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

对于存储在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());
    }

}