JavaFX—数据模型类中的可观察集合
下面是一段简单的JavaFX代码,以说明我的问题JavaFX—数据模型类中的可观察集合,java,model-view-controller,collections,javafx-2,javafx,Java,Model View Controller,Collections,Javafx 2,Javafx,下面是一段简单的JavaFX代码,以说明我的问题 List list1 = new ArrayList(); list1.add("foo"); ... someListView = new ListView<>(); ObservableList someObservableList = FXCollections.observableList(list1); someListView.setItems(someObservableList); ... someObservab
List list1 = new ArrayList();
list1.add("foo");
...
someListView = new ListView<>();
ObservableList someObservableList = FXCollections.observableList(list1);
someListView.setItems(someObservableList);
...
someObservableList.add("bar");
List list1=new ArrayList();
清单1.添加(“foo”);
...
someListView=新建ListView();
ObservableList someObservableList=FXCollections.ObservableList(列表1);
setItems(someObservableList);
...
添加(“条”);
如果我理解正确,在调用setItems
方法后,不仅列表的内容将显示在ListView
Gui组件中,而且如果项目随后添加到ObservableList
实例中,ListView
将自动刷新,并自动显示新添加的项目,无需调用任何其他add
或refresh
方法
到目前为止,一切顺利。但是,如果我在原始列表中添加了一些内容(即list1
),该怎么办呢。这些更改不会自动传播。这很有道理,但有时很不方便
当然,在一个经典的Java应用程序中,应用程序的模型并不是由ObservableCollection
实例组成的。因此,无论何时向模型添加内容,都必须更新从原始列表派生的observebleLists
实例。显然这是不可避免的,对吗
这让我想知道,从现在起,修改模型类中的集合
类型引用(例如列表
,集合
,集合
,可观察
,…)并用它们的可观察集合
替换它们,这是一个聪明的主意吗
到目前为止,我一直认为这些
ObservableCollection
类只应该在应用程序的Gui层中使用,但在任何地方使用它们似乎都很方便。您可以通过Granite Data Services Generator(用groovy GSP和Java编写)来生成“bindable”通过生成javafx属性来保存基本字段(包括集合)的数据,可以从域类中提取java类
这方面有一个很好的示例项目:它是用maven构建的,启用了generation。这指的是枯燥的原则(不要重复自己),有时域类成为可绑定的似乎更有用。您已经修改了类,使其具有javafx属性:您已经做了类似于Granite的事情,是的,它有一些优点,因为它删除了样板代码(类似于此:EJB3似乎删除了DTO,实体是域类)。但是您的域类与视图紧密耦合:它看起来像MVC模式
另一个解决方案是使用JFXtras库,它有一个有趣的API,可以在java集合上动态生成监听器来实例化javafx属性。下面是一个链接,其中介绍:
使用JFXtras,您只能在需要时使用属性,使用相对简单的API(对于集合,可能很难读取IMHO),这样您就不会修改与视图无关的域类。但是对于集合上的高级绑定:它似乎不是最好的解决方案。这看起来像是MVC和MVP之间的折衷
我看到的最后一个解决方案是坚持MVP模式,实际上您正在使用它,它最初不允许通过视图访问模型类,因为它引入了一个Presenter层来链接这两个层:
您必须在javafx属性和域类之间手动实例化和同步值:有时这是您想要的,也是实现这一点的唯一方法(例如:通过这种方式,您可以很容易地以一种形式“还原”到旧域值,如果它是可绑定的,您将丢失最后一个“正确”的域值)。请注意,您可以将javafx属性放在单例中(使用诸如Spring之类的IOC框架),以便通过不同的视图进行访问和绑定:我将它们视为演示者的一部分
我不认为有更好的解决办法:根据你的需要和喜好来选择。它甚至可以成为一场经典的MVC与MVP之争,没有赢家。一般来说,我会在模型层避免任何GUI库依赖性。这将限制可能的重用。对于javafx依赖项以及在模型类中经常(错误地)使用的AWT对象(如点/矩形),情况也是如此 原因很简单:您的代码将自身局限于平台和框架,例如Android不支持上述任何JavaUI层,如awt。此外,ORM可能在处理此类类型时遇到问题,这些类型需要为您的域对象定制适配器 我发现使用稍微修改过的模式版本也可以很好地使用javafx。在您的示例中,您将使用普通列表和适当的propertychange事件来设计模型。然后,ViewModel将作为模型的适配器,提供视图可以绑定到的ObservableList
- 使用*.fxml视图: 您必须使用javafx控制器,它只需创建到ViewModel的绑定
- 使用代码生成视图: 只需在视图中将构造函数依赖项添加到所需的ViewModel中,并在视图中将其绑定到属性
关于MVC的最后一句话:Swing和javafx都不是设计用于MVC方式的(因为控制器被合并到视图中)。MVC适用于组件,因为MVP和MVVM更适合于应用程序。此外,在模型中使用JavaFXObservables会增加对jfxrt.jar的直接依赖性,当模型是shar时,这可能会导致问题