【问题标题】:Java PropertyChangeListenerJava PropertyChangeListener
【发布时间】:2011-02-13 22:51:51
【问题描述】:

我正在尝试弄清楚如何监听另一个类中的属性更改。以下是我的代码:

ClassWithProperty 有我想听的属性:

public class ClassWithProperty {
    private PropertyChangeSupport changes = new PropertyChangeSupport(this); 
    private int usersOnline;

    public int getUsersOnline() {
        return usersOnline;
    }

    public ClassWithProperty() {
        usersOnline = 0;
        while (usersOnline<10) {
            changes.firePropertyChange("usersOnline", usersOnline, usersOnline++);
        }
    }

    public void addPropertyChangeListener(
        PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }
    public void removePropertyChangeListener(
        PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }
}

主要是我需要了解属性更改的地方:

public class Main {

    private static ClassWithProperty test;

    public static void main(String[] args) {
        test = new ClassWithProperty();
        test.addPropertyChangeListener(listen());

    }

    private static PropertyChangeListener listen() {
        System.out.println(test.getUsersOnline());
        return null;
    }

}

我只在最后一次触发了事件 (usersOnline=10)。 我是 Java 新手,试图找到解决方案,但无济于事。

【问题讨论】:

  • 可能与您的问题无关,但是您的代码中的一个问题是您在每次循环迭代时将 usersOnline 增加了两次。 ++ 只使用一次。
  • 是的,我的错误,但问题仍然存在。谢谢;)

标签: java


【解决方案1】:

代码:

private static PropertyChangeListener listen() {
    System.out.println(test.getUsersOnline());
    return null;
}

返回null,这意味着“没有对象”,这反过来意味着test.addPropertyChangeListener(listen())实际上是test.addPropertyChangeListener(null),它不会注册任何东西。

您必须将PropertyChangeListener 的有效实例传递给addPropertyChangeListener() 方法。

编辑

我建议你阅读 Java 教程中关于 PropertyChangeListeners 的章节:
http://download.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html

您的代码的另一个问题是您在ClassWithProperty 的构造函数中调用了firePropertyChange()。但是那个时候,不可能注册任何监听器,所以它没有任何作用。对addPropertyChangeListener() 的任何调用都会发生在您触发事件之后

这里是你的代码修改,所以它应该可以工作(虽然还没有测试过......):

public class ClassWithProperty {
    private PropertyChangeSupport changes = new PropertyChangeSupport(this);
    private int usersOnline = 0;

    public ClassWithProperty() {
    }

    public void setupOnlineUsers() 
    {
        while (usersOnline < 10) {
            changes.firePropertyChange("usersOnline", usersOnline, ++usersOnline);
        }
    }

    public int getUsersOnline() {
        return usersOnline;
    }

    public void addPropertyChangeListener(PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }

    public void removePropertyChangeListener(PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }
}

public class MainListener implements PropertyChangeListener {
    private ClassWithProperty test;

    public MainListener() {
        test = new ClassWithProperty();
        test.addPropertyChangeListener(this);
        test.setupOnlineUsers();
    }

    public void propertyChange(PropertyChangeEvent evt) {
        System.out.println(test.getUsersOnline());
    }

    public static void main(String[] args) {
        new MainListener(); // do everything in the constructor
    }
}

【讨论】:

  • 您能否将我的代码与示例集成?抱歉,我是 javabeginner,无法理解。对我来说,由于我的英语也很差(我来自意大利),这很难理解。非常感谢。
【解决方案2】:

我所做的是在 ClassWithProperty 类中放置一个方法:

public PropertyChangeSupport getPropertyChangeSupport() {
    return changes;
}

然后,在 Main() 类的构造函数中注册属性更改事件:

private void initializeListeners() {
    test.getPropertyChangeSupport().addPropertyChangeListener((PropertyChangeEvent event) -> {
        if (event.getPropertyName().equals("usersOnline"))   {
            String passedEventData = (String) event.getNewData(); 
        }
    });
}

这样您就不会使用已在 PropertyChangeSupport 类中的方法重复 ClassWithProperty 中的代码。

当您需要在 ClassWithProperty 类中触发事件时,请执行以下操作:

changes.firePropertyChange("usersOnline", oldValue, newValue);

这种方法的一个显着特点是,如果
event.getOldValue() 和 event.getNewValue() 相等,事件不会触发。如果要触发具有相同信息的重复事件,请在 oldValue 字段中使用 null; firePropertyChange() 方法只传递 int、boolean 和 Object。因此,如果您没有传递 int 或 boolean,则需要在接收端转换事件中传递的值。

【讨论】:

    【解决方案3】:

    你的方法在这里:

    public ClassWithProperty() {
        usersOnline = 0;
        while (usersOnline<10) {
            changes.firePropertyChange("usersOnline", usersOnline, usersOnline++);
            usersOnline++;
        }
    }
    

    有一个while循环,会不断循环并阻塞线程。我对属性更改侦听器的有限了解是它们侦听绑定属性的更改,这里是usersOnLine 变量,这意味着只有在此数字更改时才应触发属性更改(可能在任何setUserOnLineaddUserOnLine、@ 987654327@ 和类似方法)。更多绑定属性请看这里:Bound Properties

    【讨论】:

    • 你绑定属性的链接失效了,试试this
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多