【发布时间】:2012-01-05 02:00:30
【问题描述】:
我似乎无法在任何地方找到我的问题的答案。是否有任何事件侦听器可以检测布尔值或其他变量的变化然后对其进行操作。或者是否可以创建一个自定义事件侦听器来检测这一点?
我似乎无法在任何地方找到解决方案,我发现 this website 解释了如何创建自定义事件
【问题讨论】:
我似乎无法在任何地方找到我的问题的答案。是否有任何事件侦听器可以检测布尔值或其他变量的变化然后对其进行操作。或者是否可以创建一个自定义事件侦听器来检测这一点?
我似乎无法在任何地方找到解决方案,我发现 this website 解释了如何创建自定义事件
【问题讨论】:
就像您需要创建一个事件侦听器一样,您还需要创建事件触发器——因为没有什么可以为您自动执行此操作。我提供了示例代码,向您展示了如何实现这样的 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;
}
}
【讨论】:
使用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...");
}
}
【讨论】:
你也可以尝试实现一个观察者。
首先创建可观察对象:
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
【讨论】:
回答很晚,但这是一个可以通过 Observer/Observable 解决的问题。 Example
【讨论】:
您设置的布尔值应该只允许通过 setter 方法执行,例如:
public void setFlag(boolean flag){
//Method code goes here
}
现在在 now set 方法中,您可以根据传入的值、需要触发的事件来决定。我用简单的术语解释,没有引入复杂的术语,所以你可以更好地理解,所以代码 sn-p 看起来像:
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
}
如果您需要更多信息,请提出问题
【讨论】:
当您想要侦听 I/O 更改时,您可以创建一个侦听器。主要在图形上。 您的问题的答案是保持运行程序的状态,然后检查变量是否从程序无限循环内的状态发生变化。
【讨论】:
您可以为此使用 AOP,也许是 AspectJ?查看几个示例here(如果您使用 Eclipse,那么通过他们的插件使用 AspectJ 非常简单)。
对你来说,你会有一个类似于 SampleAspect 中使用的切入点,但只有当有人对布尔变量进行新的 SET 时才会使用这个切入点(这并不意味着值已经改变,只是有人将值加载到变量中)。
【讨论】: