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