用于检测变量更改的Java事件侦听器

时间:2011-11-23 19:24:46

标签: java boolean

我似乎无法在我的问题的任何地方找到答案。是否有任何事件监听器可以检测到布尔值或其他变量的更改,然后对其进行操作。或者是否可以创建自定义事件侦听器来检测此问题?

我似乎无法在任何地方找到解决方案,我发现this website解释了如何创建自定义事件

7 个答案:

答案 0 :(得分:7)

就像你需要创建一个事件监听器一样,你还需要创建一个事件触发器 - 因为没有什么是自动的,它会为你做这件事。我已经提供了示例代码,向您展示如何实现这样的firer。

此测试实施并不完美。它只包括添加侦听器的方法。您可能希望包含一种方法来删除不再对接收事件感兴趣的侦听器。另请注意,此类不是线程安全的。

import java.util.List;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.EventObject;
import java.awt.EventQueue; 

/**
 * This class uses the EventQueue to process its events, but you should only 
 * really do this if the changes you make have an impact on part of a GUI 
 * eg. adding a button to a JFrame.
 *
 * Otherwise, you should create your own event dispatch thread that can handle
 * change events
 */
public class BooleanChangeTest implements BooleanChangeDispatcher {

    public static void main(String[] args) {

        BooleanChangeListener listener = new BooleanChangeListener() {
            @Override
            public void stateChanged(BooleanChangeEvent event) {
                System.out.println("Detected change to: "
                    + event.getDispatcher().getFlag()
                    + " -- event: " + event);
            }
        };

        BooleanChangeTest test = new BooleanChangeTest(false);
        test.addBooleanChangeListener(listener);

        test.setFlag(false); // no change, no event dispatch
        test.setFlag(true); // changed to true -- event dispatched

    }

    private boolean flag;
    private List<BooleanChangeListener> listeners;

    public BooleanChangeTest(boolean initialFlagState) {
        flag = initialFlagState;
        listeners = new ArrayList<BooleanChangeListener>();
    }

    @Override   
    public void addBooleanChangeListener(BooleanChangeListener listener) {
        listeners.add(listener);
    }

    @Override
    public void setFlag(boolean flag) {
        if (this.flag != flag) {
            this.flag = flag;
            dispatchEvent();
        }
    }

    @Override
    public boolean getFlag() {
        return flag;
    }

    private void dispatchEvent() {
        final BooleanChangeEvent event = new BooleanChangeEvent(this);
        for (BooleanChangeListener l : listeners) {
            dispatchRunnableOnEventQueue(l, event);
        }
    }

    private void dispatchRunnableOnEventQueue(
                final BooleanChangeListener listener, 
                final BooleanChangeEvent event) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                listener.stateChanged(event);
            }
        });
    }

}

interface BooleanChangeDispatcher {

    public void addBooleanChangeListener(BooleanChangeListener listener);
    public boolean getFlag();
    public void setFlag(boolean flag);

}

/**
 * Listener interface for classes interested in knowing about a boolean
 * flag change.
 */
interface BooleanChangeListener extends EventListener {

    public void stateChanged(BooleanChangeEvent event);

}

/** 
 * This class lets the listener know when the change occured and what 
 * object was changed.
 */
class BooleanChangeEvent extends EventObject {

    private final BooleanChangeDispatcher dispatcher;

    public BooleanChangeEvent(BooleanChangeDispatcher dispatcher) {
        super(dispatcher);
        this.dispatcher = dispatcher;
    }

    // type safe way to get source (as opposed to getSource of EventObject
    public BooleanChangeDispatcher getDispatcher() {
        return dispatcher;
    }
}

答案 1 :(得分:7)

使用PropertyChangeSupport。你不必实现那么多,它是线程安全的。

public class MyClassWithText {
    protected PropertyChangeSupport propertyChangeSupport;
    private String text;

    public MyClassWithText () {
        propertyChangeSupport = new PropertyChangeSupport(this);
    }

    public void setText(String text) {
        String oldText = this.text;
        this.text = text;
        propertyChangeSupport.firePropertyChange("MyTextProperty",oldText, text);
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(listener);
    }
}

public class MyTextListener implements PropertyChangeListener {
    @Override
    public void propertyChange(PropertyChangeEvent event) {
        if (event.getPropertyName().equals("MyTextProperty")) {
            System.out.println(event.getNewValue().toString());
        }
    }
}

public class MyTextTest {
    public static void main(String[] args) {
        MyClassWithText interestingText = new MyClassWithText();
        MyTextListener listener = new MyTextListener();
        interestingText.addPropertyChangeListener(listener);
        interestingText.setText("FRIST!");
        interestingText.setText("it's more like when you take a car, and you...");
    }
}

答案 2 :(得分:3)

您也可以尝试实施观察者。

首先创建可观察对象:

import java.util.Observable;

public class StringObservable extends Observable {
 private String name;


 public StringObservable(String name) {
  this.name = name;
 }

 public String getName() {
  return name;
 }


 public void setName(String name) {
  this.name = name;
  setChanged();
  notifyObservers(name);
 }

}

然后是观察者:

import java.util.Observable;
import java.util.Observer;

public class NameObserver implements Observer {
 private String name;

 public NameObserver() {
  name = null;
 }

 public void update(Observable obj, Object arg) {
  if (arg instanceof String) {
   name = (String) arg;
   System.out.println("NameObserver: Name changed to " + name);
  } else {
   System.out.println("NameObserver: Some other change to subject!");
  }
 }
}

在你的主要地方(或其他地方):

public class TestObservers {
 public static void main(String args[]) {

  // Create the Subject and Observers.
  StringObservable s = new StringObservable("Test");
  NameObserver nameObs = new NameObserver();

  // Add the Observer
  s.addObserver(nameObs);


  // Make changes to the Subject.
  s.setName("Test1");
  s.setName("Test2");
 }
}

主要找到here

答案 3 :(得分:2)

回答很晚,但这是一个可以用Observer / Observable解决的问题。 Example

答案 4 :(得分:1)

您应该允许您设置的布尔值仅通过以下setter方法执行:

public void setFlag(boolean flag){
    //Method code goes here
}

现在在set方法中,您可以根据输入的值来决定需要触发的事件。我用简单的术语解释,没有引入复杂的术语,所以你可以更好地理解,所以代码片段看起来像:

public void setFlag(boolean flag){

    //if flag is TRUE do something
    //If flag is FALSE then do something 

    //And finally do what you needed to do with flag
}

如果您需要更多信息,请提出问题

答案 5 :(得分:0)

当您想要侦听I / O更改时,您可以创建一个侦听器。主要是在图形上。 你的问题的答案是保持正在运行的程序的状态,然后检查变量是否从程序的无限循环内的状态改变。

答案 6 :(得分:0)

您可以使用AOP,也许使用AspectJ?查看一些示例here(如果您使用Eclipse,那么使用AspectJ的插件非常简单。)

对于你来说,你会得到一个类似于SampleAspect中使用的切入点的切入点,但是只有当有人对一个布尔变量进行新的SET时才会使用它(这并不意味着值已经改变,只是有人为变量加载了一个值)。