2012-04-01 20 views
7

Sé que hay oyentes en JavaFX, y estoy seguro de que Java. Pero estoy confundido sobre cómo implementarlos.Agregar un oyente a una variable en Java/JavaFX a la que se llama al cambio de variable

Tengo una variable booleana que se cambia a lo largo de mi programa. Cada vez que se cambia el booleano, quiero que se ejecute una función myFunc().

¿Se puede hacer esto fácilmente?

+0

¿Nos puede mostrar algo de código? No creo que lo que estás preguntando sea posible, pero el mismo efecto se puede lograr de una manera diferente. – chandsie

Respuesta

4

Tan simple como esto:

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

y cada vez que desee cambiar la bandera booleana, que debe hacerlo a través de este método.

+3

Si utiliza la solución de esta respuesta, y si está accediendo a este procedimiento desde múltiples hilos, definitivamente desea implementar algún mecanismo de sincronización. –

0

Hay 2 soluciones para su problema

  1. El uso normal de Java, en ese caso, deberá añadir detectores para el bean (por sí mismo) y luego se invocan los métodos detectores en el método de selección (de nuevo por sí mismo), y haga que la variable sea privada, por lo que solo puede ser modificada por su método setter.
  2. La segunda solución es usar un marco AOP puro (sé que AspectJ puede hacer esto), que puede interceptar la modificación de su variable, y luego llamar a su oyente utilizando un aspecto. Mencionaré que usando @AspectJ (soporte de anotación de AspectJ), sus aspectos serían clases de Java puro, y no hay necesidad de un IDE de soporte de AspectJ.
+0

Para obtener más información sobre la primera solución, consulte la Especificación y ejemplos de JavaBeans. –

0

U puede usar el patrón de diseño Observer. Al igual que este :

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

Si está utilizando JavaFX 2 a continuación proporciona una solución fuera de la caja, tanto para la arquitectura de componentes JavaBeans y el patrón de diseño Observer. Además, ofrece una gran flexibilidad para asociar el estado de las variables con los enlaces de propiedad. El código siguiente ilustra los eventos modificados por la propiedad y el enlace de las variables de propiedad. Por supuesto, puede ajustar los descriptores de acceso a la propiedad para ocultar detalles como getFlag() y setFlag() a continuación, y usarlos en el resto de la aplicación.

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

Lo haría usando PropertyChangeListener. Aquí es un buen tutorial: http://docs.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html

Ejemplo de código:

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