2017-03-02 66 views
0

我想實現在JavaFX應用程序Observer模式。我從來沒有在這裏問過一個問題,但這讓我有點瘋狂。JavaFX和Observer模式 - 更新UI

基本上我試圖用Observer模式來監視分析真實電話號碼的文件中的類,並自動更新用戶界面的文件進行解析。

之前,我得到了我的問題,這是我的代碼:

抽象類Observer.java

public abstract class Observer 
{ 
    public PhoneBook numbers; 

    public abstract void update(); 
} 

我有一個實現此一類:

public class PhoneBookObserver extends Observer { 

    public PhoneBookObserver(PhoneBook numbers) 
    { 
     this.numbers = numbers; 
     this.numbers.attach(this); 
    } 

    @Override 
    public void update() 
    { 
     System.out.println(""NUMBER - : " + numbers.GetNumbers()); 

    } 
} 

在班級做解析,我創建了一個新的PhoneBookObserver

public PhoneBook ParsePhoneBook() 
{ 
    PhoneBook nums= new PhoneBook(); 
    PhoneBookObserver p = new PhoneBookObserver(nums); 

    // ... Parsing of file - works fine 

    return nums; 
} 

目前這個運行和PhoneBookObserver我從更新的println()輸出。

我的問題是:

  • PhoneBookObserver的更新方法可以升級我的UI給我嗎?它如何訪問我的控制器中的JavaFx元素?
  • 可我只是讓我的控制器的觀察員,覆蓋update()方法,並用它來從我的控制器內更新我的UI元素?那不好嗎?
+0

排序:[JavaFX屬性](http://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm#JFXBD107)基本上已經爲您實現了觀察者模式。爲什麼不使用這些並避免重新發明輪子? –

+0

我在哪裏添加監聽器?在初始化? –

+0

通常,是的。這取決於你如何設置,但這在大多數情況下是明顯的選擇。 (監聽器只是觀察者模式術語中的一個可觀察對象,JavaFX屬性或可觀察列表是可觀察對象。) –

回答

1

要直接回答你的問題,我可能會實現Observer作爲控制器中的內部類。然後它可以訪問控制器中的所有內容。

這裏假設PhoneBook定義表單

public List<PhoneNumber> getPhoneNumbers() ; 

的方法,那麼你可以做:

public class Controller { 

    @FXML 
    private ListView<PhoneNumber> phoneNumberList ; 

    private PhoneBook numbers = new PhoneBook() ; // or initialize from elsewhere 

    public void initialize() { 
     numbers.attach(new PhoneBookObserver(numbers)); 
     // ... 
    } 

    private class PhoneBookObserver extends Observer { 

     PhoneBookObserver(PhoneBook numbers) { 
      this.numbers = numbers ; 
     } 

     @Override 
     public void update() { 
      phoneNumberList.getItems().setAll(numbers.getPhoneNumbers()); 
     } 
    } 
} 

注意,在

public abstract class Observer 
{ 
    public PhoneBook numbers; 

    public abstract void update(); 
} 

領域numbers真的沒有任何意義,作爲唯一的方法不使用它。所以你可以刪除它(如果需要,子類可以定義這樣的字段)。然後,你可能也使它的接口,因爲它只有一個方法,它是一個@FunctionalInterface

@FunctionalInterface 
public interface Observer { 
    public void update() ; 
} 

,現在它可以用lambda表達式來實現,從而實現是如此之薄,你基本上停止有任何問題「訪問UI」:

public class Controller { 

    @FXML 
    private ListView<PhoneNumber> phoneNumberList ; 

    private PhoneBook numbers = new PhoneBook() ; // or initialize from elsewhere 

    public void initialize() { 
     numbers.attach(() -> phoneNumberList.getItems().setAll(numbers.getPhoneNumbers()); 
     // ... 
    } 

} 

最後,注意JavaFX Properties和觀察的名單基本上已經提供觀察者模式的實現,讓你幾乎在這裏重新發明輪子。你可以只是

public class PhoneBook { 

    private final ObservableList<PhoneNumber> numbers; 

    public ObservableList<PhoneNumber> getPhoneNumbers() { 
     return numbers ; 
    } 
} 

然後

public class Controller { 

    @FXML 
    private ListView<PhoneNumber> phoneNumberList ; 

    private PhoneBook numbers = new PhoneBook() ; // or initialize from elsewhere 

    public void initialize() { 
     phoneNumberList.setItems(numbers.getPhoneNumbers()); 
    } 

} 

和列表視圖將觀察號碼的(已經看到)列表供您。您沒有真正需要您的ObserverPhoneBookObserver

+0

會給這個嘗試,但在初始化方法中,我不需要在numbers.attach(新的PhoneBookObserver())中傳遞PhoneBook對象;? –

+0

是的,很抱歉,修正了這個問題。 (我已經是心態這是多餘的:)) –

+0

我已經嘗試過這一點,PhoneBookObserver中的update()方法永遠不會被觸發,我還添加了一個不輸出的println。 –