2012-04-01 20 views
7

So che ci sono listener in JavaFX e sono sicuro che Java. Ma sono confuso su come implementarli.Aggiunta di un listener a una variabile in Java/JavaFX che viene chiamata in caso di modifica variabile

Ho una variabile booleana che viene modificata nel mio programma. Ogni volta che il valore booleano viene modificato, desidero eseguire una funzione myFunc().

Questo può essere fatto facilmente?

+0

avrebbe potuto ci un certo codice mostrare? Non penso che ciò che stai chiedendo sia possibile, ma lo stesso effetto può essere ottenuto in un modo diverso. – chandsie

risposta

4

Semplice come questo:

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

e ogni volta che si desidera modificare il flag booleano, si dovrebbe farlo tramite questo metodo.

+3

Se si utilizza la soluzione di questa risposta e se si accede a questa procedura da più thread, si desidera implementare sicuramente un meccanismo di sincronizzazione. –

0

Ci sono 2 soluzioni per il vostro problema

  1. Utilizzando pianura Java, in questo caso, si deve aggiungere listener per il bean (da soli) e poi invocano i metodi listener sul metodo setter (ancora una volta da soli), e rendere la variabile privata, quindi può essere modificata solo dal metodo setter.
  2. La seconda soluzione utilizza un framework AOP puro (so che AspectJ può farlo), che può intercettare la modifica della variabile e quindi chiamare l'ascoltatore utilizzando un aspetto. Devo dire che usando @AspectJ (supporto per le annotazioni di AspectJ), i tuoi aspetti sarebbero delle classi Java pure, e non c'è bisogno di un supporto IDE per AspectJ.
+0

Per ulteriori informazioni sulla prima soluzione, consultare le specifiche e gli esempi di JavaBeans. –

0

U può utilizzare il modello di progettazione Observer. Proprio come questo:

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

Se si sta utilizzando JavaFX 2 quindi fornisce una soluzione out-of-box sia per architettura a componenti JavaBeans e design pattern Observer. Inoltre offre una grande flessibilità nell'associare lo stato delle variabili tramite le associazioni di proprietà. Il codice seguente illustra gli eventi modificati di proprietà e il binding delle variabili di proprietà. Ovviamente è possibile racchiudere i metodi di accesso alle proprietà per nascondere i dettagli come getFlag() e setFlag() di seguito e utilizzarli nel resto dell'applicazione.

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 farei utilizzando PropertyChangeListener. Ecco un bel tutorial: http://docs.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html

Esempio di codice:

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