我正在尝试在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。
我的问题是:
答案 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());
}
}
并且列表视图将为您观察(已经可观察的)数字列表。您无需Observer
或PhoneBookObserver
。