向Java/JavaFX中的变量添加侦听器,该变量在变量更改时被调用

向Java/JavaFX中的变量添加侦听器,该变量在变量更改时被调用,java,javafx,actionlistener,Java,Javafx,Actionlistener,我知道JavaFX中有监听器,我相信Java。但我对如何实现它们感到困惑 我有一个布尔变量,它在整个程序中都会改变。每次更改布尔值时,我都希望运行函数myFunc() 这很容易做到吗?就这么简单: public void changeBooleanFlag(boolean bEnabled) { if(booleanFlag == bEnabled) return; booleanFlag = bEnabled; myFunc(); } 无论何时您想要更改布尔标志,您都

我知道JavaFX中有监听器,我相信Java。但我对如何实现它们感到困惑

我有一个布尔变量,它在整个程序中都会改变。每次更改布尔值时,我都希望运行函数myFunc()

这很容易做到吗?

就这么简单:

public void changeBooleanFlag(boolean bEnabled)
{
    if(booleanFlag == bEnabled) return;
    booleanFlag = bEnabled;
    myFunc();
}

无论何时您想要更改布尔标志,您都应该通过此方法进行更改。

您的问题有两种解决方案

  • 使用纯Java,在这种情况下,您应该(自己)将侦听器添加到bean中,然后调用setter方法上的侦听器方法(同样是自己),并将变量设为私有的,因此它只能由setter方法修改
  • 第二种解决方案是使用纯AOP框架(我知道AspectJ可以做到这一点),它可以拦截对变量的修改,然后使用aspect调用侦听器。我要提到的是,使用@AspectJ(AspectJ的注释支持),您的方面将是纯Java类,并且不需要AspectJ支持IDE

  • 您可以使用观察者设计模式。 就这样,

     public interface Listener
      {
          public void handle(Object o) ;
      }
    
      public class PropertiesChangeListener
      {
          public void handle(Object o) {
            //DO SOMETHING...
          }
      }
      
      public class Bean {
          private boolean flag;
          private List<Listener> listeners = new ArrayList<Listener>();
    
          public setFlag(boolean flag) {
            this.flag = flag;
            if (listeners.size() > 0 ) {
                for (Listener l : this.listeners ) {
                    l.handle(flag); //invoke 
                }
            }
          }
    
          public registerListener(Listener listener) {
            this.listeners.add(listener);
          }
    
          //..... other fields and methods
    
      }
    
      public class Main{
    
          public static void main(String[] args) {
            Bean bean  = new Bean();
            bean.registerListener(new PropertiesChangeListener());
            bean.setFlag(true); //handler method will be invoked..
          }
      }
    
    公共接口侦听器
    {
    公共无效句柄(对象o);
    }
    公共类属性ChangeListener
    {
    公共无效句柄(对象o){
    //做点什么。。。
    }
    }
    公共类Bean{
    私有布尔标志;
    私有列表侦听器=新的ArrayList();
    公共设置标志(布尔标志){
    this.flag=flag;
    if(listeners.size()>0){
    for(Listener l:this.listeners){
    l、 句柄(标志);//调用
    }
    }
    }
    公共注册表侦听器(侦听器){
    this.listeners.add(listener);
    }
    //……其他领域和方法
    }
    公共班机{
    公共静态void main(字符串[]args){
    Bean=新Bean();
    registerListener(新属性ChangeListener());
    setFlag(true);//将调用处理程序方法。。
    }
    }
    
    如果您使用的是JavaFX2,那么它为JavaBeans组件体系结构和Observer设计模式提供了现成的解决方案。此外,它还提供了通过属性绑定关联变量状态的极大灵活性。下面的代码说明了属性更改事件和属性变量的绑定。当然,您可以像下面的
    getFlag()
    setFlag()
    那样包装属性访问器以隐藏细节,并在应用程序的其余部分使用它们

    public class Demo extends Application {
    
        private BooleanProperty booleanProperty = new SimpleBooleanProperty(true);
    
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage primaryStage) {
    
            // Add change listener
            booleanProperty.addListener(new ChangeListener<Boolean>() {
    
                @Override
                public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                    System.out.println("changed " + oldValue + "->" + newValue);
                    myFunc();
                }
            });
    
            Button btn = new Button();
            btn.setText("Toggle boolean flag");
            btn.setOnAction(new EventHandler<ActionEvent>() {
    
                @Override
                public void handle(ActionEvent event) {
                    booleanProperty.set(!booleanProperty.get()); //toggle
                    System.out.println("toggled to " + booleanProperty.get());
                }
            });
    
            // Bind to another property variable
            btn.underlineProperty().bind(booleanProperty);
    
            StackPane root = new StackPane();
            root.getChildren().add(btn);
            primaryStage.setScene(new Scene(root, 300, 250));
            primaryStage.show();
        }
    
        public boolean getFlag() {
            return booleanProperty.get();
        }
    
        public void setFlag(boolean val) {
            booleanProperty.set(val);
        }
    }
    
    公共类演示扩展了应用程序{
    私有BooleanProperty BooleanProperty=新的SimpleBoleanProperty(true);
    公共静态void main(字符串[]args){
    发射(args);
    }
    @凌驾
    公共无效开始(阶段primaryStage){
    //添加更改侦听器
    addListener(新的ChangeListener(){
    @凌驾
    public void changed(ObservalEvalue我会用它来做。这是一个很好的教程:

    代码示例:

    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.util.ArrayList;
    import java.util.List;
    
    public class MyClass {
        private final List<PropertyChangeListener> listeners = new ArrayList<>();
        private boolean b1, b2;
    
        public MyClass() {
        }
    
        public boolean isB1() {
            return b1;
        }
    
        public void setB1(boolean b1) {
            boolean oldValue = this.b1;
            this.b1 = b1;
            firePropertyChange("b1", oldValue, b1);
        }
    
        public boolean isB2() {
            return b2;
        }
    
        public void setB2(boolean b2) {
            boolean oldValue = this.b2;
            this.b2 = b2;
            firePropertyChange("b2", oldValue, b2);
        }
    
        public void addPropertyChangeListener(PropertyChangeListener listener) {
            listeners.add(listener);
        }
    
        private void firePropertyChange(String property, Object oldValue, Object newValue) {
            for (PropertyChangeListener l : listeners) {
                l.propertyChange(new PropertyChangeEvent(this, property, oldValue, newValue));
            }
        }
    
        /**
         * Main method for tests.
         * @param args
         */
        public static void main(String[] args) {
            MyClass m = new MyClass();
    
            m.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent e) {
                    String changedProperty = e.getPropertyName();
                    System.out.println("Changed property: " + changedProperty);
                    System.out.println("New value: " + e.getNewValue());
                    System.out.println("Old value: " + e.getOldValue());
                    System.out.println();
                }
            });
    
            m.setB1(true);
            m.setB2(false);
        }
    }
    
    import java.beans.PropertyChangeEvent;
    导入java.beans.PropertyChangeListener;
    导入java.util.ArrayList;
    导入java.util.List;
    公共类MyClass{
    私有最终列表侦听器=新的ArrayList();
    私有布尔b1,b2;
    公共MyClass(){
    }
    公共布尔值isB1(){
    返回b1;
    }
    公共空间1(布尔b1){
    布尔值=this.b1;
    这1.b1=b1;
    火属性更改(“b1”,旧值,b1);
    }
    公共布尔值isB2(){
    返回b2;
    }
    公共区域2(布尔值b2){
    布尔值=this.b2;
    这1.b2=b2;
    firePropertyChange(“b2”,旧值,b2);
    }
    public void addPropertyChangeListener(PropertyChangeListener侦听器){
    添加(侦听器);
    }
    私有void firePropertyChange(字符串属性、对象oldValue、对象newValue){
    for(PropertyChangeListener l:侦听器){
    l、 propertyChange(新PropertyChangeEvent(this,property,oldValue,newValue));
    }
    }
    /**
    *试验的主要方法。
    *@param args
    */
    公共静态void main(字符串[]args){
    MyClass m=新的MyClass();
    m、 addPropertyChangeListener(新的PropertyChangeListener(){
    @凌驾
    公共无效属性更改(属性更改事件e){
    字符串changedProperty=e.getPropertyName();
    System.out.println(“更改的属性:+changedProperty”);
    System.out.println(“新值:+e.getNewValue());
    System.out.println(“旧值:+e.getOldValue());
    System.out.println();
    }
    });
    m、 第1条(正确);
    m、 第2条(假);
    }
    }
    
    您能给我们看一些代码吗?我不认为您所问的是可能的,但同样的效果可以通过不同的方式实现。有关第一个解决方案的更多信息,请查看JavaBeans规范和示例。如果您使用此答案的解决方案,并且如果您从多个线程访问此过程,您肯定希望实现一些同步机制。