JavaFX 8自定义TableCell实现渲染三次

时间:2014-02-14 00:06:24

标签: java javafx-8 tablecell

我开发了一个简单的自定义TableCell来启用表中值的编辑。无论用户是否正在编辑该单元,组件的行为都会显示BigDecimalTextField,它应该始终启用该版本。该组件工作正常,只有一个奇怪的问题:当表格呈现时,而不是只显示一行,显示三行:

Rendering three times

组件的代码是:

public class BigDecimalEditingCell extends TableCell {

    private BigDecimalField spinner = new BigDecimalField(new BigDecimal("0.00"));
    private ObjectProperty<BigDecimal> campoLigado = null;

    public BigDecimalEditingCell() {
        this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        createField();
    }

    private void createField() {
        spinner.setStepwidth(new BigDecimal("0.01"));
        spinner.setMinValue(new BigDecimal("0.00"));
        spinner.setFormat(NumberFormat.getInstance());
        spinner.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
    }

    @Override
    public void updateItem(Object item, boolean empty) {
        super.updateItem(item, empty);
        criarBind();
        setGraphic(spinner);
        setText(null);
    }

    private void criarBind() {
        ObservableValue<BigDecimal> valor = getTableColumn().getCellObservableValue(getIndex());
        if (valor != null) {
            ObjectProperty<BigDecimal> propriedade = (ObjectProperty<BigDecimal>) valor;
            if (campoLigado == null) {
                spinner.numberProperty().bindBidirectional(propriedade);
                campoLigado = propriedade;
            } else if (campoLigado != propriedade) {
                spinner.numberProperty().unbindBidirectional(campoLigado);
                spinner.numberProperty().bindBidirectional(propriedade);
                campoLigado = propriedade;
            }
        }
    }    
}

如果我使用默认的TextFieldTableCell,表格会正确呈现。我有另一个组件(像这样)使用JavaFX的DatePicker并发生同样的问题。 我做错了什么?

ADDED

以下是此组件的用法:

public class ControladorPainelFormaPagamento extends ControladorPainelSubmeter {

    @FXML
    private TableView<ParcelaBean> tabela;
    @FXML
    private TableColumn<ParcelaBean, LocalDate> colunaVencimento;
    @FXML
    private TableColumn<ParcelaBean, BigDecimal> colunaValor;
    private FormaPagamentoBean bean;

    .
    .
    .

    private void configurarColunaValor() {
        colunaValor.setCellValueFactory(new PropertyValueFactory<ParcelaBean, BigDecimal>("valor"));
        colunaValor.setCellFactory(new Callback<TableColumn<ParcelaBean, BigDecimal>, TableCell<ParcelaBean, BigDecimal>>() {
            @Override
            public TableCell<ParcelaBean, BigDecimal> call(TableColumn<ParcelaBean, BigDecimal> parcelaBeanStringTableColumn) {
                return new BigDecimalEditingCell();
            }
        });
    }

    private void configurarColunaVencimento() {
        colunaVencimento.setCellValueFactory(new PropertyValueFactory<ParcelaBean, LocalDate>("dataVencimento"));
    }

    public void carregar(ModoExibicao modoExibicao, FormaPagamentoBean formaPagamento) {
        this.bean=formaPagamento;
        tabela.setItems(bean.getParcelas());
        .
        .
        .
    }

    .
    .
    .

}

如果表中使用的列表中有多个bean,我已经使用debug进行了检查。每次只有一个人在那里。

1 个答案:

答案 0 :(得分:1)

我正在查看同一系统中的另一个表并注意到这一点:当表中没有项时,不会呈现任何一行。 empty table

但是当你只添加一行时,表格呈现空行直到达到表格的高度(修复浅灰色行):

table with a row

所以,显然额外的行是由TableView添加的,这样一个简单的null检查解决了这个问题:

public class BigDecimalEditingCell extends TableCell {

    private BigDecimalField element = new BigDecimalField(new BigDecimal("0.00"));
    private ObjectProperty<BigDecimal> campoLigado = null;

    @Override
    protected void updateItem(Object item, boolean empty) {
        super.updateItem(item,empty);
        if (getIndex() < getTableView().getItems().size() && !empty) {
            createField();
            createBind();
            setGraphic(element);
            setText(null);
        } else {
            removeBind();
            setGraphic(null);
        }
    }

    .
    .
    .
}