Ich habe einen JavaFX-Service SimpleListProperty und ich möchte über einen Rückruf benachrichtigt werden, wenn der Dienst eine benutzerdefinierte Eigenschaft aktualisiert. Normalerweise ist die Art und Weise dies geschehen ist, dass der Dienst einige in Eigenschaften wie „Staat“ aufgebaut „workDone“, „Wert“ usw. Die eine am meisten ähnlich dem ich nacheifern wollen, ist der „Wert“ benannte Eigenschaft. Die Eigenschaft "value" ist in der Serviceklasse wie folgt definiert.Zuhören <T> Updates von einem JavaFX-Service
private final ObjectProperty<V> value = new SimpleObjectProperty<>(this, "value");
@Override public final V getValue() { checkThread(); return value.get(); }
@Override public final ReadOnlyObjectProperty<V> valueProperty() { checkThread(); return value; }
In my case I needed to listen to updates to a pair of message objects being updated by my JavaFX service thread, so I added a custom named property for each one as shown below.
// add 'heartbeat' bound property
private final ObjectProperty<CAServiceHeartbeatMessage> heartbeat =
new SimpleObjectProperty<>(this, "heartbeat", null);
public CAServiceHeartbeatMessage getHeartbeat() {
return heartbeat.get();
}
public void setHeartbeatMessage(CAServiceHeartbeatMessage aHeartbeat) {
heartbeat.set(aHeartbeat);
}
public ObjectProperty<CAServiceHeartbeatMessage> heartbeatProperty() {
return heartbeat;
}
// add 'memberSystemStatus' bound property
private final ObjectProperty<MemberSystemStatusMessage> memberSystemStatus =
new SimpleObjectProperty<>(this, "memberStatus", null);
public MemberSystemStatusMessage getMemberStatus() {
return memberSystemStatus.get();
}
public void setMemberSystemMessage(MemberSystemStatusMessage aMemberSystemStatus) {
memberSystemStatus.set(aMemberSystemStatus);
}
public ObjectProperty<MemberSystemStatusMessage> memberSystemStatusProperty() {
return memberSystemStatus;
}
Dann in der Controller-Klasse habe ich den folgenden Code, um die GUI auf Änderungen an jede dieser Eigenschaften basiert zu aktualisieren:
// heartbeatMessageProperty listener
// Update the GUI widgets when a new CAServiceHeartbeatMessage (heartbeatMessage) is updated
mListenerService.heartbeatProperty().addListener(
(ObservableValue<? extends CAServiceHeartbeatMessage> observer,
CAServiceHeartbeatMessage oldValue, CAServiceHeartbeatMessage newValue) -> {
// this is where we need to intelligently update the appropriate
// heartbeat service entries
System.out.println("updated CAServiceHeartbeatMessage");
});
// 'memberSystemMessage' bound property listener
mListenerService.memberSystemStatusProperty().addListener(
(ObservableValue<? extends MemberSystemStatusMessage> observer,
MemberSystemStatusMessage oldValue, MemberSystemStatusMessage newValue) -> {
if (newValue == null) {
. . .
Meine Frage ist, wie kann ich mehrere SimpleObjectProperties
ersetzen, um eine einzige SimpleListProperty
s oder SimpleMapProperty
in meiner JavaFX Service-Klasse zu verwenden. Ich bin mir nicht sicher, wie oder ob ich einer Namenskonvention für Eigenschaften folgen muss, um eine einfache Listeneigenschaft in meinem Thread verfügbar zu machen, so wie ich es mit den 2 spezifischen und separat benannten Nachrichteneigenschaften getan habe. Es ist wahrscheinlich erwähnenswert, dass diese Nachrichten eine gemeinsame Basis-Nachrichtenklasse teilen - so könnten sie in einem einfachen Listentyp gespeichert werden. Ich möchte auch ein Beispiel sehen, wie ich den Updates behandeln könnte, damit ich die GUI aktualisieren, wenn die Änderungen auftreten, insbesondere ich don'w wissen, wie die der Elemente in der Liste, um zu bestimmen oder geändert kartieren.
Dank für die ausführliche Antwort, ich bin neu in Java 8-Streams und Lambda-Ausdrücke - ich nicht wirklich verstehen, was in Botschaft los ist -> neue Observable [] {Nachricht .messageProperty()} ist eine seltsame Syntax und eher verwirrend. Auch meine Nachrichtenobjekte können nicht so geändert werden, dass sie eine StringProperty enthalten - sie sind effektiv Strukturen, die Javolution verwenden, so dass ich ihre Größe nicht ändern kann. Wie würde ich Ihr Beispiel zu einer öffentlichen Klasse MyService erweitert Service- {...} in meinem Fall innerhalb der Klasse gelten habe ich die 2 separaten SimpleObjectProperties den Ich mag würde in eine ObservableArrayList verschmelzen? –
johnco3
Wenn Sie nicht auf Änderungen der Elemente in Ihrer Nachricht Objekte hören müssen, können Sie einen 'ListChangeListener' verwenden, wie ich oben zeigte. Setzen Sie Ihre Nachrichten in eine "ObservableList", die mit dem Typ Ihrer Basis-Nachrichtenklasse paramterisiert ist, und hängen Sie den Listener an.'ObservableList messages = FXCollections.observableArrayList(); messages.addAll (status1, status2, beat1, beat2); messages.addListener (...); ' –
jns
Dadurch können Sie Änderungen sehen, die an der Nachrichtenliste vorgenommen werden, z. Fügen Sie Beat hinzu, entfernen Sie den Status, aber Sie sehen keine Änderungen am Listenelement selbst. Dafür wird der Extraktor der Factory-Methode verwendet. Es verbindet einen Listener mit der Eigenschaft, die Sie angeben, z. the messageProperty(): 'FXCollections.observableArrayList (Nachricht -> new Observable [] {message.messageProperty()})' – jns