0

我有一个表格视图,其中有一列填充了 TextField。

当我的数据很少并且我的表格没有滚动条时没有问题,所有 TextFields 都会出现。

问题是,当我向下滚动表格然后再次向上滚动时,缺少一些 TextFields。

这是我的用 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);
            }
        });

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

问候,

克里斯玛·安迪卡

4

3 回答 3

1

圣诞!您面临的问题是 JavaFX 的一个著名问题,即更新 tableview 中的项目。已经有一些解决方法,例如这里。解决方案是通过以下方式触发 tableview 的内部更新机制

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

但据我了解,此解决方案仅影响数据的更改,而不影响 tableview 节点的样式。

我也用过

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

用我的实现,但这还不够,因为当表格中的行太多并且出现滚动条时,行的更新变得一团糟。

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

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 文件应包含以下几行:

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

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

Person 类应该包含

public SimpleStringProperty firstNameProperty() {
    return firstName;
}

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

我还应该补充一点,我开始接收上面代码NullPointerException中的public void changed方法,尽管它不会影响我的程序的结果。

我希望它会帮助你,克里斯玛!还有其他人!

于 2012-12-05T06:06:48.123 回答
0

嗯,我也有同样的问题,显然只绘制可见文本字段,当我们使用滚动时不会出现,因为只绘制场景而不是 textinputcontrol ,所以我的解决方案是捕获滚动事件并在使用时调整文本字段的大小并将其恢复为原始大小,从而强制您重新绘制对象,现在出现与 textinputcontrol.forcing 重新绘制对象,现在出现与 textinputcontrol。

 tableview.addEventFilter(ScrollEvent.ANY, new EventHandler<ScrollEvent>() {
        @Override
        public void handle(ScrollEvent scrollEvent) {
           System.out.println("Scrolled.");
            for(ObservableList<TextField> i:data)
                   {
                     for(TextField j: i)
                     {
                   j.setPrefSize(141, 31);
                   j.setPrefSize(140, 30);
                     }
                   }
        }
 });
于 2013-11-02T06:30:29.283 回答
0

我只是有复选框的问题。当我快速滚动我的大桌子时,它们随机消失了。我只是通过在我的 cellFactory 中删除这一行来解决它:

   @Override
    public void updateItem(Boolean item, boolean empty) {
        super.updateItem(item, empty);
       if (empty) {
           setText(null);
           // setGraphic(null); (This line causes weird behaviour in scrolling, delete it)
        } else {
            checkBox.setSelected(item);
        }
    }
于 2013-08-02T14:32:49.913 回答