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

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

我有一个表视图,显示一个被任命者列表。每个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);  
    ...
}
javafx
2个回答
0
投票

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

});

0
投票

仅从一些小代码片段中分辨出来有点困难,但我在使用前端时的一般建议是区分模型和每个级别的渲染。这适用于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表示。

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

© www.soinside.com 2019 - 2024. All rights reserved.