简体   繁体   English

使用泛型类型构造一个ObservableList

[英]Using generic type to construct an ObservableList

I'm trying to extend the JavaFX TableView class so that I can literally pass an Entity class to it and it will display all the saved objects for that class. 我正在尝试扩展JavaFX TableView类,以便可以从字面上传递一个Entity类,它将显示该类的所有保存对象。 I'm able to make it work like this but I want my custom class to be generic enough to just accept a Class variable and take care of the rest : 我能够使它像这样工作,但是我希望我的自定义类足够通用,只接受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);
    });
}

Again, the above method works perfectly but I would have to repeat it for every table listing different data which i want to avoid. 同样,上述方法可以完美地工作,但是我必须为列出了我要避免的不同数据的每个表重复该方法。 My plan is to extend TableView with a generic type, something like this : 我的计划是使用通用类型扩展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);
            }
        }
    }
}

Adding the columns is not a problem as you can see. 如您所见,添加列不是问题。 What I don't understand is how to use my T to make something like this ObservableList : 我不明白的是如何使用我的T来生成类似ObservableList的内容:

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

I tried just replacing <Supplier> by <T> or <Class<T>> and that does not seem to be valid. 我尝试仅用<T><Class<T>>替换<Supplier> ,但这似乎无效。 I learned Java way back when this stuff barely even existed and the information i found online about it is a bit confusing to be honest. 当这些东西几乎不存在时,我就回溯到Java了,说实话,我在网上找到的有关它的信息有点令人困惑。

How can I construct my list using my T variable as a type? 如何使用T变量作为类型构造列表?

Thanks! 谢谢!

Well, this was simple, I just removed it altogether! 好吧,这很简单,我将其完全删除了! Here is the end result, just pass an entity class and a list and the table takes care of the rest! 这是最终结果,只需传递一个实体类和一个列表,表格将负责其余的工作!

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);
    }
}

The downside is that this will display column headers with the actual property name in the class (not always very user friendly). 缺点是,它将在类中显示具有实际属性名称的列标题(并不总是非常用户友好)。 Any suggestions to put something nicer in the column headers automatically will be welcome! 欢迎任何建议自动在列标题中添加更好的内容!

EDIT 编辑

For my column names, i ended up creating a custom annotation called FriendlyName with just a value parameter. 对于我的列名,我最终创建了一个仅带有值参数的自定义批注,名为FriendlyName。 I now populate the column headers like this : 现在,我像这样填充列标题:

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

TableColumn column = new TableColumn(friendlyName.value());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM