在JavaFX中使用复选框更新TableRow

在JavaFX中使用复选框更新TableRow,java,javafx,Java,Javafx,我正在制作一个具有TableView的应用程序。此TableView有4列,其中第一列使用复选框。TableView中显示的数据来自一个Bill类,其名称、dateDue和Amount构成其他3列。 选中复选框(启动时的默认值)后,表中的所有票据均显示为白色。如果未选中复选框,则该行上的票据需要“重影”或更改字符的颜色 在我的fxml文件中,我使用了以下代码: 关联的BillCheckBox类: 公共类BillsCheckBox实现回调{ @凌驾 public observeValue call

我正在制作一个具有TableView的应用程序。此TableView有4列,其中第一列使用复选框。TableView中显示的数据来自一个Bill类,其名称、dateDue和Amount构成其他3列。 选中复选框(启动时的默认值)后,表中的所有票据均显示为白色。如果未选中复选框,则该行上的票据需要“重影”或更改字符的颜色

在我的fxml文件中,我使用了以下代码:

关联的BillCheckBox类:

公共类BillsCheckBox实现回调{ @凌驾 public observeValue callTableColumn.CellDataFeatures参数{ 账单=param.getValue; 复选框=新复选框; checkBox.selectedProperty.setValuetrue; checkBox.selectedProperty.addListenerov、旧值、新值->{ ifbill.isSelected==false{ bill.setSelectedtrue; }否则{ bill.setSelectedfalse; } }; 返回新的SimpleObjectPropertycheckBox; } } 在控制器类中:

billsTable.setRowFactoryrow->new TableRow{ @凌驾 public void updateItemBill bill,布尔值为空{ super.updateItembill,为空; 如果bill==null | |空{ 固定方式; }否则{ //现在“bill”在这一行中包含了账单的所有信息 如果bill.isSelected==真{ //现在,我们在行的所有单元格中应用更改
forint i=0;i首先,您不应该使用cellValueFactory来确定表格单元格的可视表示形式。这是cellFactory的责任。cellValueFactory只公开数据本身

已存在用于此目的的TableCell实现+工厂:

下面的代码假定您的Bill类提供selectedProperty方法,该方法提供一个BooleanProperty,其中包含调用setSelected时修改的选定属性的值

要修改行的外观,我建议使用CSS和伪类:

这样做的另一个好处是允许您为选定的行指定不同的样式:

.表格行单元格:重影:选定。表格单元格{ -外汇文本填充:红色; }
感谢您对CellValueFactory、CellFactory和CheckBoxTableCell使用的反馈。我将进一步调查这些。您的代码帮助我解决了这个问题。
checkBoxSelectionColumn.setCellValueFactory(cd -> cd.getValue().selectedProperty());
checkBoxSelectionColumn.setCellFactory(CheckBoxTableCell.forTableColumn(checkBoxSelectionColumn));
final PseudoClass ghosted = PseudoClass.getPseudoClass("ghosted");

billsTable.setRowFactory(row -> new TableRow<Bill>(){

    private final InvalidationListener l = o -> {
        pseudoClassStateChanged(ghosted, getItem().isSelected());
    };
    private final WeakInvalidationListener listener = new WeakInvalidationListener(l);

    @Override
    public void updateItem(Bill bill, boolean empty){
        // remove listener from last item
        Bill oldItem = getItem();
        if (oldItem != null) {
            oldItem.selectedProperty().removeListener(listener);
        }

        super.updateItem(bill, empty);

        if (bill == null || empty) {
            pseudoClassStateChanged(ghosted, false);
        } else {
            // add listener & update
            bill.selectedProperty().addListener(listener);
            l.invalidated(null);
        }
    }
});