Слушатель событий Java для обнаружения изменения переменной

Я не могу найти ответ нигде на мой вопрос. Есть ли какой-либо прослушиватель событий, который может обнаружить изменение логической или другой переменной, а затем действовать на нее. Или можно создать пользовательский прослушиватель событий, чтобы обнаружить это?

Пожалуйста, я не могу найти решение этого в любом месте, и я нашел этот сайт, объяснив, как создавать пользовательские события

Ответ 1

Так же, как вам нужно создать прослушиватель событий, вам также необходимо создать event 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;
    }
}

Ответ 2

Используйте 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 more like when you take a car, and you...");
    }
}

Ответ 3

вы также можете попытаться реализовать Observer.

Сначала создайте наблюдаемый объект:

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

В основном найдено здесь

Ответ 4

Очень поздно ответить, но это проблема, которая может быть решена с помощью Observer/Observable. Пример

Ответ 5

Логическое значение, которое вы устанавливаете, должно разрешаться только с помощью метода сеттера, например:

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

Теперь в методе set now вы можете решить, на основе того, какое значение входит, какое событие нужно уволить. Я просто объясняю, не вводя сложные термины, чтобы вы могли понять лучше, поэтому фрагмент кода будет выглядеть так:

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
}

Задайте вопросы, если вам нужна дополнительная информация

Ответ 6

вы создаете прослушиватель, когда хотите прослушивать изменения ввода-вывода. в основном по графике. ответ на ваш вопрос заключается в том, чтобы сохранить состояние запущенной программы, а затем проверить, изменяются ли переменные из состояния внутри бесконечного цикла вашей программы.

Ответ 7

Вы можете использовать AOP для этого, возможно, AspectJ? Проверьте несколько примеров здесь (если вы используете Eclipse, то использование AspectJ очень просто с их плагином).

Для вас у вас будет pointcut, аналогичный тому, который используется в SampleAspect, но тот, который будет использоваться только тогда, когда кто-то делает новый SET для булевой переменной (это не означает, что значение изменилось, просто что кто-то загрузил значение в переменную).