聆听SimpleListProperty<;T>;来自JavaFX服务的更新

聆听SimpleListProperty<;T>;来自JavaFX服务的更新,java,javafx,javafx-2,observable,Java,Javafx,Javafx 2,Observable,我有一个JavaFX服务,当服务更新自定义属性时,我希望通过回调得到通知。通常,这样做的方式是服务具有一些内置属性,如“state”、“workDone”、“value”等。最类似于我要模拟的属性是“value”命名属性。“value”属性在服务类中定义如下 private final ObjectProperty<V> value = new SimpleObjectProperty<>(this, "value"); @Override public

我有一个JavaFX服务,当服务更新自定义属性时,我希望通过回调得到通知。通常,这样做的方式是服务具有一些内置属性,如“state”、“workDone”、“value”等。最类似于我要模拟的属性是“value”命名属性。“value”属性在服务类中定义如下

    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;
    }    
private final ObjectProperty value=new SimpleObjectProperty(这个“值”);
@重写公共最终V getValue(){checkThread();返回值.get();}
@重写公共最终ReadOnlyObjectProperty valueProperty(){checkThread();返回值;}
在我的例子中,我需要监听由JavaFX服务线程更新的一对消息对象的更新,因此我为每个对象添加了一个自定义命名属性,如下所示。
//添加“heartbeat”绑定属性
私有最终ObjectProperty检测信号=
新的SimpleObject属性(此“heartbeat”,null);
public CAServiceHeartbeatMessage getHeartbeat(){
返回heartbeat.get();
}
public void setHeartbeatMessage(CAServiceHeartbeatMessage aHeartbeat){
心跳。设定(A心跳);
}
公共对象属性heartbeatProperty(){
返回心跳;
}
//添加“memberSystemStatus”绑定属性
私有最终ObjectProperty memberSystemStatus=
新的SimpleObject属性(此“memberStatus”,null);
公共成员系统状态消息getMemberStatus(){
返回memberSystemStatus.get();
}
public void setMemberSystemMessage(MemberSystemStatusMessage aMemberSystemStatus){
memberSystemStatus.set(aMemberSystemStatus);
}
公共对象属性memberSystemStatusProperty(){
返回成员系统状态;
}    
然后,在控制器类中,我添加了以下代码,以根据对每个属性的更改来更新GUI:

// 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) {
//heartbeatMessageProperty侦听器
//更新新CAServiceHeartbeatMessage(heartbeatMessage)时更新GUI小部件
mListenerService.heartbeatProperty().addListener(

(ObservalEvalue要监听列表中元素的更改,您可以使用
FXCollections
的工厂方法初始化
ObservalElist

 ObservableList<Message> messages = FXCollections.observableArrayList(message -> new Observable[] { message.messageProperty() });
构造由指定列表支持的ObservableList。ObservableList实例上的变异操作将报告给已在该实例上注册的观察者。 请注意,直接对基础列表进行的突变操作不会报告给任何封装该列表的ObservableList的观察者。 此列表还使用提取器报告其中元素的突变。提取器返回的可观察对象(应用于每个列表元素)被侦听更改并转换为ListChangeListener的“更新”更改

public void changelister(){
ObservableList messages=FXCollections.observableArrayList(message->new Observable[]{message.messageProperty()});
messages.addListener((ListChangeListener)c->{
while(c.next()){
debug(“change:{}”,c);
如果(c.wasAdded()){

List要监听列表中元素的更改,您可以使用
FXCollections
的工厂方法初始化
ObservableList

 ObservableList<Message> messages = FXCollections.observableArrayList(message -> new Observable[] { message.messageProperty() });
构造由指定列表支持的ObservableList。ObservableList实例上的变异操作将报告给已在该实例上注册的观察者。 请注意,直接对基础列表进行的突变操作不会报告给任何封装该列表的ObservableList的观察者。 此列表还使用提取器报告其中元素的突变。提取器返回的可观察对象(应用于每个列表元素)被侦听更改并转换为ListChangeListener的“更新”更改

public void changelister(){
ObservableList messages=FXCollections.observableArrayList(message->new Observable[]{message.messageProperty()});
messages.addListener((ListChangeListener)c->{
while(c.next()){
debug(“change:{}”,c);
如果(c.wasAdded()){

List感谢您的详细回答,我对Java8流和lambdas还不熟悉-我不太了解message->new Observable[]{message.messageProperty()}中的内容这是一种奇怪的语法,相当令人困惑。此外,我的消息对象不能修改为包含StringProperty-它们是使用Javolution的有效结构,因此我无法更改其大小。我如何将您的示例应用于公共类MyService extends Service{…}在我的类中,我有两个单独的SimpleObjectProperties,我想将它们合并到ObservableArrayList中?如果您不需要监听消息对象中元素的更改,您可以使用一个
ListChangeListener
,如我上面所示。将消息放在一个
ObservableList
参数化的列表中基本消息类的类型并附加侦听器。
observeList messages=FXCollections.observearraylist();messages.addAll(status1、status2、beat1、beat2);messages.addListener(…);
这将允许您查看对消息列表所做的更改,例如添加节拍、删除状态,但您不会看到对列表元素本身所做的更改。这就是factory方法的提取器的用途。它将侦听器附加到您指定的属性,例如messageProperty():
FXCollections.observearraylist(message->newobserveable[]{message.messageProperty()})
感谢您的详细回答,我对Java8流和lambdas不熟悉-我不太了解message->newobserveable[]{message.messagePro中的内容
 public void changeListener() {

        ObservableList<Message> messages = FXCollections.observableArrayList(message -> new Observable[] { message.messageProperty() });

        messages.addListener((ListChangeListener<Message>) c -> {

            while (c.next()) {
                LOGGER.debug("change: {}", c);

                if (c.wasAdded()) {
                    List<? extends Message> addedSubList = c.getAddedSubList();
                }
                if (c.wasUpdated()) {
                    int from = c.getFrom();
                    int to = c.getTo();
                    List<? extends Message> subList = c.getList().subList(from, to);
                }
            }
        });

        HearBeat beat = new HearBeat("beat");

        messages.add(beat);
        messages.add(new Status("status"));

        beat.setMesssage("beat changed");
        beat.setMesssage("beat changed again");

        messages.addAll(new Status("1"), new Status("2"));
    }

    public abstract class Message {

        private StringProperty message;

        Message(String message) {
            this.message = new SimpleStringProperty(message);
        }

        public StringProperty messageProperty() {
            return message;
        }

        public String getMesssage() {
            return message.get();
        }

        public void setMesssage(String val) {
            message.set(val);
        }
    }

    public class HearBeat extends Message {

        public HearBeat(String message) {
            super(message);
        }
    }

    public class Status extends Message {

        Status(String message) {
            super(message);
        }
    }