将侦听器添加到Java / JavaFX中的变量,该变量在变量变量时被调用

时间:2012-04-01 23:47:12

标签: java javafx actionlistener

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

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

这可以轻松完成吗?

5 个答案:

答案 0 :(得分:24)

如果您使用的是JavaFX 2,那么它为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);
    }
}

答案 1 :(得分:4)

这很简单:

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

并且每当您想要更改布尔标志时, 通过此方法执行此操作。

答案 2 :(得分:4)

我会使用PropertyChangeListener来做。这是一个很好的教程:http://docs.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html

代码示例:

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

答案 3 :(得分:1)

你可以使用Observer设计模式。 就像这样:

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

答案 4 :(得分:0)

您的问题有两种解决方案

  1. 使用普通Java,在这种情况下,你应该为你的bean添加监听器(由你自己),然后在setter方法上调用监听器方法(再次由你自己),并使变量私有 ,所以它只能通过你的setter方法修改。
  2. 第二种解决方案是使用纯AOP框架(我知道AspectJ可以这样做),它可以拦截变量的修改,然后使用方面调用你的监听器。我将提到使用@AspectJ(AspectJ的注释支持),您的方面将是纯Java类,并且不需要AspectJ支持IDE。