将整数映射到组合框中的自定义类的字符串

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将整数映射到组合框中的自定义类的字符串相关的知识,希望对你有一定的参考价值。

我有一个表视图,显示一个被任命者列表。每个appointe都有一个分配给它的组,该组的id保存在appointe类中。

我想在tablecell中显示一个组合框,显示所选组和所有其他存在的组。我可以在单元格工厂中设置组合框的项目,但我无法设置相应被任命者的选定值。

我有一个方法,当我向它提供id时,从可观察列表返回组。这意味着我需要在cellfactory中的id,但我没有找到一种方法来做到这一点。我还需要显示组的名称,而不是参考clas。有没有办法做到这一点,或者我应该改变我的方法?

任命班

public class Appointee {

private SimpleIntegerProperty id;
private SimpleStringProperty firstname;
private SimpleStringProperty lastname;
private SimpleIntegerProperty group;
private SimpleIntegerProperty assigned;

public Appointee(int id, String firstname, String lastname, int group, int assigned){
    this.id = new SimpleIntegerProperty(id);
    this.firstname = new SimpleStringProperty(firstname);
    this.lastname = new SimpleStringProperty(lastname);
    this.group = new SimpleIntegerProperty(group);
    this.assigned = new SimpleIntegerProperty(assigned);
}

小组课

public class Group {
private IntegerProperty id;
private StringProperty name;
private IntegerProperty members;
private IntegerProperty assigned;

public Group(int id, String name, int members, int assigned) {
    this.id = new SimpleIntegerProperty(id);
    this.name = new SimpleStringProperty(name);
    this.members = new SimpleIntegerProperty(members);
    this.assigned = new SimpleIntegerProperty(assigned);
}

appointe表视图

public AppointeeTableView() {
    // define table view
    this.setPrefHeight(800);
    this.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
    this.setItems(MainController.appointeeObervableList);
    this.setEditable(true);

    // define columns
    ...
    TableColumn groupCol = new TableColumn("Group"); // group
    groupCol.setCellFactory(col -> {
        TableCell<Group, StringProperty> c = new TableCell<>();
        final ComboBox<String> comboBox = new ComboBox(MainController.groupObservableList);
        c.graphicProperty().bind(Bindings.when(c.emptyProperty()).then((Node) null).otherwise(comboBox));
        return c;
    });
    groupCol.setEditable(false);  
    ...
}
答案

覆盖updateItemTableCell方法来更新单元格,确保新值保存在TableCell值的更改上并使用cellValueFactory

final Map<Integer, Group> groupById = ...
final ObservableList<Integer> groupIds = ...
TableColumn<Group, Number> groupCol = new TableColumn<>("Group");
groupCol.setCellValueFactory(cd -> cd.getValue().groupProperty());

class GroupCell extends ListCell<Integer> {

    @Override
    protected void updateItem(Integer item, boolean empty) {
        super.updateItem(item, empty);

        Group group = groupById.get(item);

        if (empty || group == null) {
            setText("");
        } else {
            setText(group.getName());
        }
    }

}

groupCol.setCellFactory(col -> new TableCell<Group, Integer>() {

    private final ComboBox<Integer> comboBox = new ComboBox<>(groupIds);
    private final ChangeListener<Integer> listener = (o, oldValue, newValue) -> {
        Group group = (Group) getTableView().getItems().get(getIndex());
        group.setGroup(newValue);
    };

    {
        comboBox.setCellFactory(lv -> new GroupCell());
        comboBox.setButtonCell(new GroupCell());
    }

    @Override
    protected void updateItem(Number item, boolean empty) {
        super.updateItem(item, empty);

        if (empty || item == null) {
            setGraphic(null);
        } else {
            comboBox.valueProperty().removeListener(listener);
            setGraphic(comboBox);
            comboBox.setValue((Integer) item);
            comboBox.valueProperty().addListener(listener);
        }
    }

});
另一答案

仅从一些小代码片段中分辨出来有点困难,但我在使用前端时的一般建议是区分模型和每个级别的渲染。这适用于JavaFX,Swing和Angular应用程序。

被任命者TableView可能应该是TableView<Appointee>

对于appointee.group属性,您有两个选择:使用Group或(例如,当从/向JSON序列化时会产生太多重复数据)然后使用业务键。第一个选项通常更容易实现和使用。使用第二个选项,您需要一些服务/代码才能转换回Group,并且必须考虑您希望在何种级别进行转换。

让我们继续使用第二个选项,因为您当前已指定appointee.group为整数。

在这种情况下,组列应该是TableColum<Appointee, Integer>。然后小组细胞应该是TableCell<Appointee, Integer>

到目前为止,我们只讨论了模型,而不是渲染,除了我们想要在表格中显示任命者。

我建议在下一级也这样做。

不要将ComboBox<String>用于组comboBox,而是使用ComboBox<Group>。 String是您想要在comboBox中呈现组的方式,但Group是模型。此外,业务键的类型ComboBox<Integer>有点误导(因为你想要一个组合组合框,而不是整数组合框),并限制了代码的灵活性。

在预先选择comboBox中的值时,请使用我提到的转换服务/代码。

组单元格应该具有类型ListCell<Group>,并且在updateItem方法中,它涉及如何呈现组,您可以例如使用name属性来获取String表示。

当然,这种方法有各种变化,但请确保在每个级别上您都知道控件的模型是什么以及控件的渲染器是什么。始终使用模型设计代码,并仅在最低渲染级别使用渲染类型。

以上是关于将整数映射到组合框中的自定义类的字符串的主要内容,如果未能解决你的问题,请参考以下文章

片段中的自定义列表适配器

java - 如何将responseEntity映射到java中的自定义类

Three.js 中的自定义纹理着色器

使用 Dozer 的自定义转换器将对象列表映射到另一个列表

EF Core 5 - 如何将 EF.Functions.Like 与映射到 JSON 字符串的自定义属性一起使用?

Java中的自定义异常捕获方式