2012-04-01 22 views
7

Wiem, że w JavaFX są słuchacze, a ja na pewno Java. Ale jestem zdezorientowany, jak je wdrożyć.Dodawanie detektora do zmiennej w Javie/JavaFX, która jest wywoływana przy zmianie zmiennej

Mam zmienną typu boolean, która jest zmieniana przez cały mój program. Za każdym razem, gdy zmieniana jest wartość boolean, chcę uruchomić funkcję myFunc().

Czy można to łatwo zrobić?

+0

można pokazać nam jakiś kod? Nie sądzę, że to, o co prosisz, jest możliwe, ale ten sam efekt można osiągnąć w inny sposób. – chandsie

Odpowiedz

4

Tak proste, jak to:

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

i kiedy chcesz zmienić flagę logiczną, ty powinny zrobić za pośrednictwem tej metody.

+3

Jeśli używasz rozwiązania tego rozwiązania i jeśli uzyskujesz dostęp do tej procedury z wielu wątków, zdecydowanie chcesz zaimplementować mechanizm synchronizacji. –

0

Są 2 rozwiązania dla swojego problemu

  1. użyciu zwykłego Java, w tym przypadku, będziecie dodawać słuchaczy do fasoli (przez siebie), a następnie wywołać metody słuchacza setter (ponownie przez siebie) i ustaw zmienną jako prywatną, więc można ją modyfikować tylko za pomocą metody ustawiającej.
  2. Drugim rozwiązaniem jest użycie czystego schematu AOP (wiem, że AspectJ może to zrobić), który może przechwycić modyfikację zmiennej, a następnie wywołać swojego słuchacza za pomocą aspektu. Wspomnę, że używając @AspectJ (obsługa adnotacji AspectJ), twoje aspekty będą czystymi klasami Java i nie ma potrzeby korzystania z IDE wsparcia AspectJ.
+0

Aby uzyskać więcej informacji na temat pierwszego rozwiązania, spójrz na specyfikację JavaBeans i przykłady. –

0

U może używać wzoru projektu Observer. Właśnie tak:

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

Jeśli używasz JavaFX 2 to zapewnia out-of-box rozwiązań zarówno dla architektury komponentów JavaBeans i obserwator wzorca projektowego. Ponadto daje dużą elastyczność w powiązaniu stanu zmiennych przez powiązania właściwości. Poniższy kod ilustruje zmiany właściwości zdarzeń i wiązanie zmiennych właściwości. Oczywiście można zawijać obiekty uzupełniające do właściwości, aby ukryć szczegóły, jak poniżej: getFlag() i setFlag() i używać ich w pozostałej części aplikacji.

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

Zrobiłbym to używając PropertyChangeListener. Tu jest ładny poradnik: http://docs.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html

Przykład kodu:

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); 
    } 
} 
Powiązane problemy