Javafx和Observer模式-更新UI [英] Javafx and the Observer pattern - updating a UI

查看:38
本文介绍了Javafx和Observer模式-更新UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to implement the Observer pattern in a JavaFx application. I've never asked a question here but this is driving me a bit crazy.

基本上,我试图使用观察者"模式来监视正在解析电话号码文件的类,并在解析文件时自动更新UI.

Essentially I'm trying to use the Observer pattern to monitor a class that's parsing a file of phone numbers, and update the UI automatically as the file is parsed.

在我提出问题之前,这是我的代码:

Before I get to my questions, here is my code:

抽象类Observer.java

public abstract class Observer 
{
   public PhoneBook numbers;

   public abstract void update();
}

我有一个实现此目的的类:

I have a class that implements this:

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

In the class doing the parsing, I've created a new PhoneBookObserver

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

    // ... Parsing of file - works fine

   return nums;
}

当前运行,并输出PhoneBookObserver中update()的println.

Currently this runs and my println from update() in PhoneBookObserver is output.

我的问题是:

  • PhoneBookObserver的更新方法可以为我更新UI吗?它将如何访问控制器中的JavaFx元素?
  • 我可以仅使控制器成为观察者,重写update()并使用该值从控制器内部更新UI元素吗?那不好吗?

推荐答案

要直接回答您的问题,我可能将 Observer 实现为控制器中的内部类.然后,它可以访问控制器中的所有内容.

To directly answer your question, I would probably implement the Observer as an inner class in the controller. Then it has access to everything in the controller.

假设此处 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 :

the field numbers really serves no purpose, as the only method doesn't use it. So you could remove it (subclasses can define such a field if they need). Then you may as well make it an interface, and since it only has one method, it's a @FunctionalInterface:

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

现在它可以使用lambda表达式实现,因此实现是如此之薄,以至于您基本上不再遇到访问UI"的任何问题:

and now it can be implemented with a lambda expression, so the implementation is so thin that you basically stop having any issues with "accessing the 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属性和可观察的列表基本上已经提供了观察者模式的实现,因此您在这里几乎是在重新发明轮子.你可以拥有

Finally, note that JavaFX Properties and observable lists basically already provide an implementation of the observer pattern, so you're pretty much reinventing the wheel here. You could just have

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 .

and the list view will observe the (already-observable) list of numbers for you. There is no real need for your Observer or PhoneBookObserver.

这篇关于Javafx和Observer模式-更新UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆