使用泛型类型构造ObservableList

问题描述 投票:0回答:1

我正在尝试扩展JavaFX TableView类,以便我可以直接将Entity类传递给它,它将显示该类的所有已保存对象。我能够使它像这样工作但我希望我的自定义类足够通用,只接受一个Class变量并处理其余的:

private void showSuppliers()
{
    tabPane.getTabs().stream().filter((tab) -> (tab.getText().compareTo("Fournisseurs") == 0)).map((tab) -> (VBox)tab.getContent()).forEachOrdered((vBox) -> 
    {
        TableView<Supplier> table = new TableView<>();

        TableColumn nameColumn = new TableColumn("Nom");
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));

        TableColumn addressColumn = new TableColumn("Addresse");
        addressColumn.setCellValueFactory(new PropertyValueFactory<>("address"));

        TableColumn contactColumn = new TableColumn("Contact");
        contactColumn.setCellValueFactory(new PropertyValueFactory<>("contactPerson"));

        TableColumn phoneNumberColumn = new TableColumn("Téléphone");
        phoneNumberColumn.setCellValueFactory(new PropertyValueFactory<>("phoneNumber"));

        TableColumn emailColumn = new TableColumn("Courriel");
        emailColumn.setCellValueFactory(new PropertyValueFactory<>("emailAddress"));

        TableColumn creationDateColumn = new TableColumn("Date de création");
        creationDateColumn.setCellValueFactory(new PropertyValueFactory<>("enteredDate"));

        table.getColumns().addAll(nameColumn, addressColumn, contactColumn, phoneNumberColumn, emailColumn, creationDateColumn);

        ObservableList<Supplier> suppliers = FXCollections.observableArrayList(supplierService.findAll());
        table.setItems(suppliers);

        vBox.getChildren().add(table);
    });
}

同样,上面的方法可以很好地工作,但我必须为列出我想避免的不同数据的每个表重复它。我的计划是使用泛型类型扩展TableView,如下所示:

public class EntityTable<T> extends TableView<T>
{
    private final Class<T> entityClass;

    public EntityTable(Class<T> entityClass) 
    {
        this.entityClass = entityClass;

        init();
    }

    private void init()
    {
        for (Field field : entityClass.getDeclaredFields())
        {
            if ((field.getType() != Set.class) && (field.getName().compareTo("id") != 0))
            {
                TableColumn column = new TableColumn(field.getName());
                column.setCellValueFactory(new PropertyValueFactory<>(field.getName()));

                getColumns().add(column);
            }
        }
    }
}

您可以看到,添加列不是问题。我不明白的是如何使用我的T来制作像这样的ObservableList:

ObservableList<Supplier> suppliers = FXCollections.observableArrayList(supplierService.findAll());

我尝试用<Supplier><T>替换<Class<T>>,这似乎没有效果。当这些东西几乎不存在时我学会了Java,而且我在网上找到的关于它的信息说实话有点令人困惑。

如何使用我的T变量作为类型构建我的列表?

谢谢!

java tableview type-inference generic-type-argument
1个回答
0
投票

嗯,这很简单,我只是完全删除了它!这是最终结果,只需传递一个实体类和一个列表,该表将处理其余的事情!

public class EntityTable<T> extends TableView<T>
{
    private final Class<T> entityClass;

    private final List<T> entityList;

    public EntityTable(Class<T> entityClass, List<T> entityList) 
    {
        this.entityClass = entityClass;
        this.entityList = entityList;

        init();
    }

    private void init()
    {
        for (Field field : entityClass.getDeclaredFields())
        {
            if ((field.getType() != Set.class) && (field.getName().compareTo("id") != 0))
            {
                TableColumn column = new TableColumn(field.getName());
                column.setCellValueFactory(new PropertyValueFactory<>(field.getName()));

                getColumns().add(column);
            }
        }

        ObservableList list = FXCollections.observableArrayList(entityList);
        setItems(list);
    }
}

缺点是这将显示列标题与类中的实际属性名称(并不总是非常用户友好)。任何建议自动在列标题中添加更好的东西将是受欢迎的!

编辑

对于我的列名,我最终创建了一个名为FriendlyName的自定义注释,只有一个值参数。我现在填充列标题,如下所示:

FriendlyName friendlyName = field.getAnnotation(FriendlyName.class);

TableColumn column = new TableColumn(friendlyName.value());
© www.soinside.com 2019 - 2024. All rights reserved.