TableCell里面的Spinner没有更新值

时间:2017-01-17 16:56:57

标签: javafx

我创建了一个简单的TableView,它使用来自数据库的数据,我想要的只是能够使用JavaFx轻松更改该表的数字列的值。

但是......因为我有一些心理问题,所以我无法使它发挥作用。

下面是“SpinnerCell”组件,我遇到的问题是,即使在触发commitEdit之后,当我从TableView获取项目时,没有更改任何值。我在此更新生命周期中遗漏了什么?

import javafx.scene.control.Spinner;
import javafx.scene.control.TableCell;

public class SpinnerTableCell<S, T extends Number> extends TableCell<S, T> {

    private final Spinner<T> spinner;

    public SpinnerTableCell() {
        this(1);
    }

    public SpinnerTableCell(int step) {
        this.spinner = new Spinner<>(0, 100, step);
        this.spinner.valueProperty().addListener((observable, oldValue, newValue) -> commitEdit(newValue));
    }

    @Override
    protected void updateItem(T c, boolean empty) {
        super.updateItem(c, empty);

        if (empty || c == null) {
            setText(null);
            setGraphic(null);
            return;
        }

        this.spinner.getValueFactory().setValue(c);

        setGraphic(spinner);
    }

}

1 个答案:

答案 0 :(得分:2)

由于您的表格单元格始终显示编辑控件(Spinner),因此您可以绕过通常的表格单元格机制来开始编辑。例如,在TextFieldTableCell中,如果单元格未处于编辑状态,则会显示标签。当用户双击单元格时,它会进入编辑状态:单元格editingProperty()设置为true,封闭TableView&#39; s {{ 1}}设置为当前单元格的位置等。

在您的情况下,由于这种情况从未发生过,editingCellProperty()对于单元格始终为isEditing(),因此false成为无操作。

请注意,commitEdit()的实现方式类似:documentation强调了这一事实。 (复选框表格单元格通过CheckBoxTableCell实现自己的属性直接更新。)

所以这里有两个选项:一个是当微调器获得焦点时进入编辑状态。您可以通过将以下内容添加到单元格的构造函数来执行此操作:

selectedStateCallback

另一种选择是为&#34;直接更新&#34;提供回调。所以你可以这样做:

this.spinner.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
    if (isNowFocused) {
        getTableView().edit(getIndex(), getTableColumn());
    }
});

然后给出表的模型类,比如说

public SpinnerTableCell(BiConsumer<S,T> update, int step) {
    this.spinner = new Spinner<>(0, 100, step);

    this.spinner.valueProperty().addListener((observable, oldValue, newValue) -> 
        update.accept(getTableView().getItems().get(getIndex()), newValue));
}

你可以做到

public class Item {
    private int value ;
    public int getValue() { return value ;}
    public void setValue(int value) { this.value = value ;}

    // ...
}