滚动JavaFX后,TableView中的TextField消失了 [英] TextField inside TableView gone after scroll JavaFX

查看:232
本文介绍了滚动JavaFX后,TableView中的TextField消失了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表格视图,里面有一个用TextField填充的列。

I have a table view and inside it, there is one column filled with TextField.

当我的数据很少而且我的表没有表格时没有问题滚动条,显示所有TextField。

There is no problem when I have few data and my table do not have scroll bar, all TextFields appears.

问题是,当我向下滚动表格然后再次上升时,会丢失一些TextField。

The problem is, when I scroll down my table and then goes up again, some TextFields are missing.

这是填充TextField的列的代码:

Here is my code for the column filled with TextField:

purchaseQtyCol.setCellFactory(
                new Callback<TableColumn< TransactionModel, TextField>, TableCell< TransactionModel, TextField>>() {
                    @Override
                    public TableCell< TransactionModel, TextField> call(final TableColumn< TransactionModel, TextField> p) {
                        TableCell<TransactionModel, TextField> cell = new TableCell<TransactionModel, TextField>() {


                            @Override
                            public void updateItem(TextField item, boolean empty) {
                                super.updateItem(item, empty);
                                if (item != null) {
                                    /**
                                     * for(CheckBox cbb : canceledCB) {
                                     * if(item.equals(cbb))
                                     * System.out.println("aa" +
                                     * this.indexProperty().getValue() + " " +
                                     * item.isSelected() ); }*
                                     */
                                    this.setGraphic(item);
                                }

                            }

                        };

                        cell.setAlignment(Pos.CENTER);
                        return cell;
                    }
                });

        purchaseQtyCol.setCellValueFactory(new Callback<CellDataFeatures<TransactionModel, TextField>, ObservableValue<TextField>>() {
            @Override
            public ObservableValue<TextField> call(final CellDataFeatures<TransactionModel, TextField> p) {

                    System.out.println("new textfield");
                    final TextField qtyField = new TextField() {
                        @Override
                        public void replaceText(int start, int end, String text) {

                            if (text.matches("[0-9]") || text.equals("")) {
                                super.replaceText(start, end, text);
                                if (this.getText().isEmpty()) {
                                    p.getValue().setPurchaseQty(0);
                                    p.getValue().setTotalPrice(0);
                                } else {
                                    p.getValue().setPurchaseQty(Integer.parseInt(this.getText()));
                                    p.getValue().setTotalPrice(p.getValue().purchaseQtyProperty().intValue() * p.getValue().basePriceProperty().intValue());
                                }
                                recountTotals();
                            }
                        }

                        @Override
                        public void replaceSelection(String text) {

                            if (text.matches("[0-9]") || text.equals("")) {
                                super.replaceSelection(text);
                                if (this.getText().isEmpty()) {
                                    p.getValue().setPurchaseQty(0);
                                    p.getValue().setTotalPrice(0);
                                } else {
                                    p.getValue().setPurchaseQty(Integer.parseInt(this.getText()));
                                    p.getValue().setTotalPrice(p.getValue().purchaseQtyProperty().intValue() * p.getValue().basePriceProperty().intValue());
                                }
                                recountTotals();
                            }
                        }
                    };

                    qtyField.setText("" + p.getValue().purchaseQtyProperty().getValue());
                    qtyField.setAlignment(Pos.CENTER_RIGHT);

                return new SimpleObjectProperty(qtyField);
            }
        });

我真的很感谢你们的帮助。

I really appreciate helps from you guys.

问候,

Chrisma Andhika

Chrisma Andhika

推荐答案

Chrisma!您遇到的问题是JavaFX关于更新tableview中项目的一个着名问题。已经有一些解决方法,例如此处。解决方案是通过

Chrisma! The problem you face is a famous issue for JavaFX about updating items in tableview. There is already some workaround about it, for example here. The solution was to trigger tableview's internal update mechanism by

tableview.getColumns().get(0).setVisible(false);
tableview.getColumns().get(0).setVisible(true);

但据我所知,这个解决方案仅影响数据的变化,而不影响tableview节点的样式。

But as far as I could understand this solution affected only changes of data, not the style of tableview's nodes.

我还用过

@Override
public void updateItem(Object item, boolean empty)

我的实现,但这还不够,因为当表中有太多行,滚动条出现了行的更新变得非常混乱。

with my implementation, but it was not enough, because when there were too many rows in a table and scroll bar appeared the updating of rows became an absolute mess.

我需要的是突出显示所有可见使用css满足一些标准的行。我通过以下方式实现了这一点:

What I needed is to make highlighted all visible rows satifying some criteria by using css. I achieved that in the following way:

Callback<TableView<Person>, TableRow<Person>> callBack = 
    new Callback<TableView<Person>, TableRow<Person>>() {
        @Override
        public TableRow<Person> call(TableView<Person> tableView) {
              final TableRow<Person> row = new TableRow<Person>() {
                     @Override
                     public void updateItem(Person item, boolean empty) {
                          super.updateItem(item, empty);
                          if(!empty && item.getFirstName() == "John") {
                              getStyleClass().add("john");
                          }
                     }
               };
               row.visibleProperty().addListener(new ChangeListener() {
                     @Override
                     public void changed(ObservableValue observableValue, Object t, Object t1) {
                         Boolean oldValue = (Boolean)t;
                         Boolean newValue = (Boolean)t1;
                         if(oldValue && !newValue) {
                             row.getStyleClass().remove("john");
                         }
                         if(!oldValue && newValue) {
                             if(row.getItem().getFirstName() == "John")
                                 row.getStyleClass().add("john");
                         }
                     }
               });
               return row;
        }
};
tableview.setRowFactory(callBack);

css文件应包含以下行:

The css file should contain the following lines:

.john {
-fx-background-color: forestgreen;
-fx-text-fill: white;
-fx-border-style: solid;
}

当然,您可以选择不同的行样式。

Of course you may choose different styling of rows.

Person类应该包含

The Person class should contain

public SimpleStringProperty firstNameProperty() {
    return firstName;
}

如您所见,我将监听器添加到 VisibleProperty 一行,我控制每行的css行为。在某些情况下,这个想法可能有助于解决tableview中的数据更新问题,而不仅仅是行样式。

As you can see I added the listener to the VisibleProperty of a row, where I control the css behavior of each row. Maybe this idea could help to solve data update in tableview in some cases, not just rows styling.

我应该添加我开始收到上面代码中 public void changed 方法中的NullPointerException ,虽然它不会影响我的程序结果。

I should aslo add that I started receiving the NullPointerException in the public void changed method in the code above, although it doesn't affect the result of my programm.

我希望它能帮到你,Chrisma!还有其他人!

I hope it will help you, Chrisma! And others as well!

这篇关于滚动JavaFX后,TableView中的TextField消失了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆