Javafx和Observer模式 - 更新UI

时间:2017-03-02 21:18:46

标签: javafx

我正在尝试在JavaFx应用程序中实现Observer模式。我从来没有在这里问过一个问题,但这让我有点疯狂。

基本上我试图使用Observer模式来监控解析电话号码文件的类,并在解析文件时自动更新UI。

在我回答我的问题之前,这是我的代码:

抽象类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中update()的println。

我的问题是:

  • PhoneBookObserver的更新方法可以为我更新我的UI吗?它如何访问我的控制器中的JavaFx元素?
  • 我可以让我的控制器成为观察者,覆盖update()并使用它来更新我的控制器中的UI元素吗?那不好吗?

1 个答案:

答案 0 :(得分:2)

要直接回答您的问题,我可能会将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表达式实现,因此实现非常简单,您基本上不会遇到任何问题&#34;访问UI&#34;:

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