JavaFX 8:从视图中分离模型/域

时间:2017-02-03 22:00:21

标签: java model-view-controller javafx model javafx-8

我只是在学习JavaFX 8.看起来如果你想在一个控件中显示一些东西,比如一个TableColumn,你需要把它作为ObservableValue的一个实例,例如,{ {1}}。

因此,在常用的SimpleStringProperty对象中,我可能有一个Person用于" firstName",然后我可以将其用作{{{ 1}},像这样:

SimpleStringProperty

但是,TableColumn就是我所说的"域" class - 我的模型可以自由引用和使用的东西。我不希望我的域和模型层知道/依赖于使用JavaFX显示应用程序的事实。

我是否正确地认为模型/域应该在这方面保持纯粹?如果是这样,使用JavaFX实现这一目标的最佳方法是什么?例如,我应该以某种方式为我的域对象编写适配器类,以便使用TableColumn<Person, String> firstNameCol = new TableColumn<Person, String>("First Name"); firstNameCol.setCellValueFactory( new PropertyValueFactory<Person, String>("firstName"));

来呈现它们

3 个答案:

答案 0 :(得分:5)

保持域模型纯粹是明智的,而不是将其绑定到任何特定框架,因为您可能需要在其他上下文中使用这些对象(数据库存储,在REST API中公开它们,进行批处理等)。 )。

更改您的域模型以使用JavaFX属性会为您在其他场景中需要避免的类增加许多额外的包袱。

但是,JavaFX确实有一种处理这种情况的标准方法,因此您可以轻松地将域模型连接到其控件,并且使用其javafx.beans.property.adapter包中的适配器以您已建议的方式工作。

然而,使用这些适配器不会让您的控件响应域对象中的值更改,例如SimpleStringProperty

如果这是一个问题,它将取决于您的要求,但如果是,您可以考虑修改您的域模型对象以添加PropertyChangeListener支持。这是一个相对较轻的权重更改(相对于完整的JavaFX属性),并且不会让您依赖于JavaFX(仅在问题较少的java.beans上)。

有关如何直接在JavaFX中使用域模型类的详细说明,请参阅此答案:JavaBean wrapping with JavaFX Properties

答案 1 :(得分:2)

为什么要避免使用任何 JavaFX类?

JavaFX属性(在javafx.beans.property包中找到)只是常规JavaBeans属性的扩展。
它们是JavaFX Properties and Bindings框架的一部分,它不依赖于JavaFX Toolkit来实现其功能,也不需要您的应用程序利用JavaFX UI类来构建其图形用户界面。 因此,它可以在代码中的任何位置用作独立工具,而不必担心模型/域与视图的特定实现相关联。

您应该将JavaFX Properties和Bindings框架视为一个通用实用程序,由于其性质,它本身与视图的实现无关,就像任何其他通用库(例如Guava)一样。例如,您可以随时切换到Swing应用程序,同时仍然继续使用它。

但如果您仍然希望尽可能不利用其功能,那么您可以实际执行此操作: 如果要呈现的内容不会发生变化(例如,您的域类中对应于表模型的状态是不可变的),并且存在标准属性getter,那么,根据PropertyValueFactory documentation

  

尝试致电get<property>()is<property>()时,可以获得支持。如果存在与此模式匹配的方法,则此方法返回的值将包含在ReadOnlyObjectWrapper中并返回到TableCell。但是,在这种情况下,这意味着TableCell将无法观察ObservableValue的更改。

避免使用适配器;它们只能用于遗留代码,不能以任何方式改变。

相关文章

答案 2 :(得分:0)

JRebirth的下一个版本(活动开发中的8.6.0)将允许使用注释处理器从POJO(Plain Old Java Object)生成这些FXJO(javaFX Java Object)。

或直接解析ecore文件。

它可以让您有机会不使用属性等UI相关内容来改变您的业务模型。