Java Event Listener to detect a variable change

让人想犯罪 __ 提交于 2021-02-06 08:50:33

问题


I cannot seem to find an answer anywhere to my question. Is there any event listener which can detect the changing of a boolean or other variable and then act on it. Or is it possible to create a custom event listener to detect this?

Please I cannot seem to find a solution to this anywhere and I found this website explaining how to create custom events


回答1:


Just like you need to create an event listener, you will also need to create the event firer -- since there is nothing automatic that will do this for you. I've provided sample code that shows you how to implement such a firer.

This test implementation isn't perfect. It only includes a way to add listeners. You may wish to include a way to remove listeners who are no longer interested in receiving events. Also note that this class is not thread-safe.

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;
    }
}



回答2:


Use PropertyChangeSupport. You wont have to implement as much and it is thread safe.

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...");
    }
}



回答3:


you can also try to implement an Observer.

First create the observable object:

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);
 }

}

Then the observer:

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!");
  }
 }
}

And in your main (or wherever else):

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");
 }
}

Mostly found here




回答4:


Very late to answer, but this is a problem that can be solved with Observer/Observable. Example




回答5:


The boolean you are setting should be allowed to do only through a setter method like:

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

Now in now set method, you can decide based on what value comes in, what event needs to be fired. I am explaining in simple terms without introducing complex terms so you can understand better, so code snippet would look like:

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
}

Ask questions if you need more info




回答6:


you create a listener when you want to listen for I/O changes. mostly on graphics. the answer to your question is to keep state of the running program, then check if variables change from the state inside the infinite loop of your program.




回答7:


You can use AOP for that, perhaps AspectJ? Check a few examples here (if you use Eclipse, then using AspectJ is really simple with their plugin).

For you, you would have a pointcut similar to the one used in the SampleAspect, but one that will only be used when someone makes a new SET to a boolean variable (this doesn't mean that the value has changed, just that someone loaded a value to the variable).



来源:https://stackoverflow.com/questions/8247926/java-event-listener-to-detect-a-variable-change

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!