【问题标题】:Spinner inside TableCell not updating valueTableCell 内的微调器不更新值
【发布时间】:2017-01-17 16:56:57
【问题描述】:

我创建了一个简单的 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);
    }

}

【问题讨论】:

    标签: javafx


    【解决方案1】:

    因为您的表格单元格始终显示编辑控件(Spinner),所以您绕过通常的表格单元格机制来开始编辑。例如,在TextFieldTableCell 中,如果单元格未处于编辑状态,则会显示一个标签。当用户双击单元格时,进入编辑状态:单元格的editingProperty()设置为true,包围TableVieweditingCellProperty()设置为当前单元格的位置等。

    在您的情况下,由于这永远不会发生,isEditing() 始终是单元格的false,因此,commitEdit() 成为无操作。

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

    所以这里有两种选择:一种是在微调器获得焦点时进入编辑状态。您可以通过将以下内容添加到单元格的构造函数来做到这一点:

    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 ;}
    
        // ...
    }
    

    你可以的

    TableView<Item> table = ... ;
    TableColumn<Item, Integer> valueCol = new TableColumn<>("Value");
    valueCol.setCellValueFactory(cellData -> new SimpleIntegerProperty(cellData.getValue().getValue()).asObject());
    valueCol.setCellFactory(tc -> new SpinnerTableCell<>(Item::setValue, 1));
    

    【讨论】:

    • 我希望使用第一种方法,但它会导致错误,现在当您单击递增/递减按钮时,微调器值不会执行任何操作。
    • 嗯,第二个效果很好。非常感谢你的帮助。很抱歉让你回答这么简单的问题。
    • @MBarni 哦,这是一个有趣的 :)。第一种方法对我来说很好;听起来你可能通过 onEditCommit 处理程序进入了某个无限循环,或者其他什么......?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多