【问题标题】:design to keep helper methods in javafx project设计以在 javafx 项目中保留辅助方法
【发布时间】:2016-12-12 13:57:28
【问题描述】:

这可能更多是设计选择,我想“为什么要重新发明轮子”。可能有人已经要求这样做了。

(我不想使用任何第三方框架,因为我的项目是一个小项目。我已经在使用 Adam Bein 的afterburner.fx)。我正在 javafx 中实现一个独立的应用程序。我对关注 MVC/MVP/MVVM 非常感兴趣。由于 javafx 允许我使用 fxml 分离 UI,因此我通过 fxml 实现了大部分 UI 设计。但是我遇到了一些问题。

我的结构

  • TradeView.fxml(我所有的 UI 设计都在这里)
  • TradeController(我所有的 UI 事件处理(还有一些业务逻辑)都在这里)
  • Trade(实体类)

现在我的fxml 中有一个JavaFX TableView。所有TableColumns 都在fxml 本身中定义。我想绑定到我的列的值是通过PropertyValueFactory 实现的,如果它是我的实体类中的直接属性。

TableView<Trade> myTableView;

例如:

<TableColumn fx:id="tradeOidTableColumn" prefWidth="130.0" text="Trade Oid">
    <cellValueFactory><PropertyValueFactory property="oid"/></cellValueFactory>
</TableColumn>

但我想在其中Commodity 是与我的Trade 实体相关的另一个实体的列中显示商品短名称。所以我可以使用

myTradeEntity.commodity().commodityShortName();

获取价值,这非常有效。但是你们知道我不能这样做fxml。它不支持嵌套绑定。

不可能

<cellValueFactory><PropertyValueFactory property="commodity.commodityShortName"/></cellValueFactory>

所以我不得不使用单元格值工厂。我定义了一个类CommodityCellValueFactory 并绑定它。 例如:

<TableColumn fx:id="commodityTableColumn" prefWidth="220.0" text="Commodity">
    <cellValueFactory><CommodityCellValueFactory /></cellValueFactory>
</TableColumn>  

基本上我想摆脱单元工厂和单元值工厂,除非我需要对我的值进行一些格式化。所以我想我可以创建一个名为

的属性
String tempCommodityShortName;
String getTempCommodityShortName()
{
    return commodity.commodityShortName();
}

在我的Trade 实体中并将其绑定到我的表格列。但我有大约 15 到 20 处房产。如果我在我的实体类中执行此操作,那么它会因这些额外的辅助方法而变得臃肿,而我不想这样做。

我想为TradeEntityHelper/TradeEntityBusiness/TradeEntityAdditions 这样的每个实体创建一个辅助类,我可以在其中拥有所有辅助方法并在表格视图列中访问它。

我的第一次尝试是代替class,我选择了一个接口(因为java 8接口支持默认方法)

interface ITradeEntityHelper
{
//all helper methods goes here
}

class TradeEntity implements ITradeEntityHelper
{
//real entity methods goes here
}

我会将接口绑定到我的TableViewTableView&lt;ITradeEntityHelper&gt; 而不是 TableView&lt;TradeEntity&gt; 如果我在尝试一些愚蠢的事情,请纠正我

现在的问题是如何在我的ITradeEntityHelper 界面中获取我的TradeEntity 参考,以便我可以询问

tradeEntity.Commodity().commodityShortName().

(或)喜欢这些

interface ITrade{}
class Trade implements ITrade{}
class TradeAdditions implements ITrade{}

将辅助方法保留在 Additions 类中。

我也想为我的 Controller 类实现同样的效果。

例如:
我的Application 中的每个 Controller 类都应该有基本接口,我希望在其中定义一些默认的 java Predicates 和 java 8 Functions 并希望在控制器类中重新使用。

class TradeController implements ITradeController, Initializable
{
}

【问题讨论】:

  • 我不确定我是否完全理解你,但看看default methods。另外,请记住,在 Java 中,与 C# 相比,接口可以有静态方法。
  • 嘿,我知道接口中的默认方法和静态方法。但我的问题是,如果我实现一个接口并编写如下所示的默认方法。为了获得我对这种情况“commodityShortName”感兴趣的值,我需要在界面中引用我的交易实体。所以我可以说tradeEntity.commodity().commodityShortName()。我缺乏的数据。默认 public ExternalComment getCommodityShortName() { return tradeEntityForWhichINeedCommodityShortName.commodity().commodityShortName(); }

标签: java design-patterns javafx java-8


【解决方案1】:

您可以使用Bindings.select 通过多级层次结构选择值。这允许您创建单个 cellValueFactory 类:

import java.util.Arrays;
import javafx.beans.NamedArg;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.util.Callback;

public class NestedPropertyValueFactory<S, T> implements Callback<TableColumn.CellDataFeatures<S, T>, ObservableValue<T>> {

    private final String[] steps;
    private final PropertyValueFactory firstStepSelector;

    /**
     * @param property a string containing the names of the properties seperated
     * by '.'.
     */
    public NestedPropertyValueFactory(@NamedArg("property") String property) {
        String[] properties = property.split("\\.");
        firstStepSelector = new PropertyValueFactory<>(properties[0]);
        this.steps = Arrays.copyOfRange(properties, 1, properties.length);
    }

    @Override
    public ObservableValue<T> call(TableColumn.CellDataFeatures<S, T> param) {
        // use PropertyValueFactory for first step and Bindings.select for
        // additonal steps.
        return Bindings.select(firstStepSelector.call(param), steps);
    }

}

这个类可以在fxml文件中作为cellValueFactory使用。

<cellValueFactory>
    <NestedPropertyValueFactory property="commodity.commodityShortName"/>
</cellValueFactory>

请注意,如果任何中间步骤产生null,您将在System.err 中收到警告。

此外,对于此类,您还需要使用符合命名约定的属性方法,即在这种情况下,方法的名称应为 commodityPropertycommodityShortNameProperty(或 getCommoditygetCommodityShort,因为它们不是可观察)。

【讨论】:

  • 感谢费边。让我试着更新你。正如我已经问过的,我还想将与特定实体相关的所有谓词和一些我经常调用的便捷方法移动到一个单独的接口或另一个与我的实体类相等的类。任何想法?再次感谢以上回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-20
  • 2018-03-12
  • 2015-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多