如何在第一组上使SimpleProperty通知侦听器?

时间:2018-10-19 14:20:47

标签: java javafx properties listener

当我写这篇文章时:

import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;

SimpleBooleanProperty foo = new SimpleBooleanProperty();
foo.addListener(
    new ChangeListener<Boolean>() {
        @Override
        public void changed(
             ObservableValue<? extends Boolean> observable,
             Boolean oldValue, Boolean newValue
        ) {
            System.out.println(oldValue + " " + newValue);                    
        }
    }
);
foo.set(false);
foo.set(true);

输出为

false true

但是,如果我将最后两行更改为

foo.set(true);
foo.set(false);

输出为

false true
true false

我发现这很不一致。如何确保始终在第一个set上通知监听器?

...还是在通常情况下,侦听器应显式调用foo.get()以获取初始值,然后仅在发生更改时得到通知?在那种情况下,我仍然不知道如何区分默认的false和在侦听器注册之前设置的false

2 个答案:

答案 0 :(得分:4)

这是完全一致的。

问题是SimpleBooleanProperty已初始化为false 。当您第一次调用foo.set(false)时,该值实际上并未更改,因此不会调用该侦听器。

第一次调用foo.set(true)时,该值将更改两次(false-> true-> false),这将两次调用侦听器。

如果您希望初始值为true,请使用the constructor which takes a boolean


如果您想在附加侦听器时触发事件,则可以很容易地扩展SimpleBooleanProperty,尽管我不清楚您将使用旧值(我想是空)是什么

class FireWhenAttachBooleanProperty extends SimpleBooleanProperty
{
    @Override
    public void addListener(ChangeListener<? super Boolean> listener)
    {
        super.addListener(listener);
        listener.changed(this, null, getValue());
    }
}

答案 1 :(得分:0)

也许这个问题尚不清楚(如果是的话,我想我不必问这个问题了;)。我的错误是我实际上想对两种不同的事情做出反应:每次设置值时都应通知一种侦听器,而仅在更改值时才通知另一种侦听器。所以我实际上需要这样的东西:

 ImageLoader image = new ImageLoader();
    JSONParser parser = new JSONParser();
    try {
        JSONObject file = (JSONObject) parser.parse((new FileReader("save_data.json")));
        image.generateShape(file);

    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

我可以这样写:

import javafx.event.EventHandler;
import java.util.ArrayList;
import javafx.event.ActionEvent;
import javafx.event.Event;

class Foo {
    private SimpleBooleanProperty foo = new SimpleBooleanProperty();
    private ArrayList<EventHandler> listener = new ArrayList<>();
    public void set(Boolean value) {
        foo.set(value);
        ActionEvent e = new ActionEvent();
        for(EventHandler l : listener) l.handle(e);
    }
    public void addChangeListener(ChangeListener<Boolean> x) { 
        foo.addListener(x); 
    }
    public void addEventHandler(EventHandler a){
        listener.add(a);
    }
}

即使认为该值不会更改,也会通知事件处理程序。