如何设置单元格背景颜色(JavaFX、tableview)

如何设置单元格背景颜色(JavaFX、tableview),java,javafx,tableview,javafx-8,Java,Javafx,Tableview,Javafx 8,我有TableView,它用于显示由CostDataRow对象生成的数据。表视图中的大多数单元格都是可编辑的,并保存整数数据,因此下面是我如何初始化表及其可编辑数字列之一的摘录: // `data` is `ObservableList<CostDataRow>` made by // using `FXCollections.<CostDataRow>observableArrayList(...)`. FilteredList<CostDataRow>

我有
TableView
,它用于显示由
CostDataRow
对象生成的数据。表视图中的大多数单元格都是可编辑的,并保存整数数据,因此下面是我如何初始化表及其可编辑数字列之一的摘录:

// `data` is `ObservableList<CostDataRow>` made by 
// using `FXCollections.<CostDataRow>observableArrayList(...)`.
FilteredList<CostDataRow> filteredData = new FilteredList<>(data, n -> true);
table.setEditable(true);
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
table.getSelectionModel().setCellSelectionEnabled(true);
table.setItems(filteredData);
// ...
// Below is "wireWeight" column (Integer data)
wireWeightTCol.setCellValueFactory(new PropertyValueFactory<>("wireWeight"));
wireWeightTCol.setCellFactory(TextFieldTableCell.<CostDataRow, Integer>forTableColumn(new StringConverter<Integer>() {
    @Override
    public String toString(final Integer value) {
        return value.toString() + " kg";
    }
    @Override
    public Integer fromString(final String s) {
        return Integer.parseInt(s.replace(" kg", ""));
    }
}));
wireWeightTCol.setOnEditCommit(
    new EventHandler<CellEditEvent<CostDataRow, Integer>>() {
        @Override
        public void handle(CellEditEvent<CostDataRow, Integer> t) {
            CostDataRow row = (CostDataRow) t.getTableView().getItems().get(t.getTablePosition().getRow());
            int weight = t.getNewValue();
            row.setWireWeight(t.getNewValue());
            // Calculate wire price
            row.setWirePrice((int)(weight * getWirePriceConstant()));
            // Refresh table view
            t.getTableView().refresh();
        }
    }
);
颜色应从与数据自身相同的数据模型中保存/加载


谢谢你的帮助

我浏览了一下,发现:

setStyle("-fx-background-color: x");

这就是您要做的吗?

如果您有css,您可以使用以下代码:

.table-row-cell:selected {
   -fx-background-color: yellow;
}

无法从TableView检索单元格实例。但问题的解决方案是使用自定义的
TableCell
类,并根据指定的条件对其进行编程以进行更改

但是请注意,一个单元实例可以用于多个项目(例如,它们被重用以提高性能)

扩展
TableCell
类时,最重要的重写方法是
updateItem()
方法。以下是如何根据条件更改样式的示例

   @Override
    protected void updateItem(LocalDate item, boolean empty) {
        super.updateItem(item, empty);

        if (item == null || empty) {
            setText(null);
            setStyle(""); // set cell style
        } else {
            if (checkCondition) {
                setTextFill(Color.CHOCOLATE);
                setStyle("-fx-background-color: red;");// set your css style here if condition is true
            } else {
                setTextFill(Color.BLACK);
                setStyle(""); // reser style if condition is false.
            }
        }
    }

根据我的经验/观点,这样做的诀窍是正确地表示模型中所需的数据。在本例中,您似乎需要表模型中的一些(或者全部)属性来携带关联的属性。我将为那些带有该属性的属性创建一个特定的类。例如,如果希望用户能够验证表中的值,则基本上希望表中的每个单元格都显示该值以及该值的当前“验证状态”。因此,您需要一个类来封装一个值和一个应该是可观察的验证状态。所以你可以这样做:

public class VerifiableValue<T> {

    public enum VerificationState { UNVERIFIED, VERIFIED, ERROR }

    private final T value ;
    private final ObjectProperty<VerificationState> verificationState = new SimpleObjectProperty<>(VerificationState.UNVERIFIED) ;

    public VerifiableValue(T value) {
        this.value = value ;
    }

    public VerifiableValue(T value, VerificationState verificationState) {
        this(value);
        setVerificationState(verificationState);
    }



    public T getValue() {
        return value ;
    }

    public final ObjectProperty<VerificationState> verificationStateProperty() {
        return this.verificationState;
    }


    public final VerifiableValue.VerificationState getVerificationState() {
        return this.verificationStateProperty().get();
    }


    public final void setVerificationState(
            final VerifiableValue.VerificationState verificationState) {
        this.verificationStateProperty().set(verificationState);
    }


}
公共类可验证值{
公共枚举验证状态{未验证,已验证,错误}
私人最终T值;
private final ObjectProperty verificationState=新的SimpleObject属性(verificationState.UNVERIFIED);
公开可验证值(T值){
这个值=值;
}
公共可验证值(T值,验证状态验证状态){
这(价值);
设置验证状态(验证状态);
}
公共T getValue(){
返回值;
}
公共最终对象属性验证StateProperty(){
返回此.verificationState;
}
公共最终可验证值。验证状态getVerificationState(){
返回此.verificationStateProperty().get();
}
公共最终无效设置验证状态(
最终可验证值。验证状态验证状态){
this.verificationStateProperty().set(verificationState);
}
}
现在创建观察表中当前项的验证状态的表单元格。因此,例如,给定一个
tableColumnWeightColumn
,您可以执行以下操作:

weightColumn.setCellFactory(tc -> {
    TextFieldTableCell<Product, VerifiableValue<Double>> cell = new TextFieldTableCell<>();

    cell.setConverter(new StringConverter<VerifiableValue<Double>>() {

        @Override
        public String toString(VerifiableValue<Double> item) {
            return item == null ? "" : String.format("%.3f Kg", item.getValue());
        }

        @Override
        public VerifiableValue<T> fromString(String string) {
            T value = new Double(string.replace("Kg","").trim());
            VerifiableValue.VerificationState verificationState = cell.getItem() == null ? VerifiableValue.VerificationState.UNVERIFIED : cell.getItem().getVerificationState() ;
            return new VerifiableValue<>(value, verificationState);
        }

    });

    ChangeListener<VerifiableValue.VerificationState> verifiedListener = (obs, oldState, newState) -> {
        if (newState == null || newState == VerifiableValue.VerificationState.UNVERIFIED) {
            cell.setStyle("");
        } else if (newState == VerifiableValue.VerificationState.VERIFIED) {
            cell.setStyle("-fx-background-color: yellow ;");
        } else if (newState == VerifiableValue.VerificationState.ERROR) {
            cell.setStyle("-fx-background-color: red ;");
        }
    };


    cell.itemProperty().addListener((obs, oldItem, newItem) -> {
        if (oldItem != null) {
            oldItem.verificationStateProperty().removeListener(verifiedListener);
        }
        if (newItem == null) {
            cell.setStyle("");
        } else {
            if (newItem.getVerificationState() == null || newItem.getVerificationState() == VerifiableValue.VerificationState.UNVERIFIED) {
                cell.setStyle("");
            } else if (newItem.getVerificationState() == VerifiableValue.VerificationState.VERIFIED) {
                cell.setStyle("-fx-background-color: yellow ;");
            } else if (newItem.getVerificationState() == VerifiableValue.VerificationState.ERROR) {
                cell.setStyle("-fx-background-color: red ;");
            }               
            newItem.verificationStateProperty().addListener(verifiedListener);
        }
    });

    return cell ;
});
weightColumn.setCellFactory(tc->{
TextFieldTableCell=新TextFieldTableCell();
cell.setConverter(新的StringConverter(){
@凌驾
公共字符串到字符串(可验证值项){
return item==null?”:String.format(“%.3f Kg”,item.getValue());
}
@凌驾
来自字符串的公共可验证值(字符串){
T值=新的双精度(string.replace(“Kg”),trim();
VerifiableValue.VerificationState VerificationState=cell.getItem()=null?VerifiableValue.VerificationState.UNVERIFIED:cell.getItem().getVerificationState();
返回新的可验证值(值,验证状态);
}
});
ChangeListener verifiedListener=(obs、oldState、newState)->{
if(newState==null | | newState==VerifiableValue.VerificationState.UNVERIFIED){
cell.setStyle(“”);
}else if(newState==VerifiableValue.VerificationState.VERIFIED){
cell.setStyle(“-fx背景色:黄色;”);
}else if(newState==VerifiableValue.VerificationState.ERROR){
cell.setStyle(“-fx背景色:红色;”);
}
};
cell.itemProperty().addListener((obs、oldItem、newItem)->{
if(oldItem!=null){
oldItem.verificationStateProperty().RemovelListener(verifiedListener);
}
if(newItem==null){
cell.setStyle(“”);
}否则{
if(newItem.getVerificationState()==null | | newItem.getVerificationState()==VerifiableValue.VerificationState.UNVERIFIED){
cell.setStyle(“”);
}else if(newItem.getVerificationState()==VerifiableValue.VerificationState.VERIFIED){
cell.setStyle(“-fx背景色:黄色;”);
}else if(newItem.getVerificationState()==VerifiableValue.VerificationState.ERROR){
cell.setStyle(“-fx背景色:红色;”);
}               
newItem.verificationStateProperty().addListener(verifiedListener);
}
});
返回单元;
});
这是一张SSCCE。我将最重要的部分移到了代码的顶部(因此事情的顺序不同寻常),并将表格单元格的创建移到了减少重复代码的方法中。在现实生活中,我可能会为此滚动我自己的表格单元格,因此标签显示“Kg”,但它们不会出现在文本字段中,并在文本字段上使用文本格式设置程序来防止无效输入。我还将把样式移出单元实现代码,使用CSS伪类来表示单元的“视图状态”,并使用外部样式表将这些状态实际映射到颜色

import java.util.Random;
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class CellHighlightingTable extends Application {

    public static class VerifiableValue<T> {

        public enum VerificationState { UNVERIFIED, VERIFIED, ERROR }

        private final T value ;
        private final ObjectProperty<VerificationState> verificationState = new SimpleObjectProperty<>(VerificationState.UNVERIFIED) ;

        public VerifiableValue(T value) {
            this.value = value ;
        }

        public VerifiableValue(T value, VerificationState verificationState) {
            this(value);
            setVerificationState(verificationState);
        }



        public T getValue() {
            return value ;
        }

        public final ObjectProperty<VerificationState> verificationStateProperty() {
            return this.verificationState;
        }


        public final CellHighlightingTable.VerifiableValue.VerificationState getVerificationState() {
            return this.verificationStateProperty().get();
        }


        public final void setVerificationState(
                final CellHighlightingTable.VerifiableValue.VerificationState verificationState) {
            this.verificationStateProperty().set(verificationState);
        }


    }

    private <T> TableCell<Product, VerifiableValue<T>> createTableCell(String format, Function<String, T> supplier) {
        TextFieldTableCell<Product, VerifiableValue<T>> cell = new TextFieldTableCell<>();

        cell.setConverter(new StringConverter<VerifiableValue<T>>() {

            @Override
            public String toString(VerifiableValue<T> item) {
                return item == null ? "" : String.format(format, item.getValue());
            }

            @Override
            public VerifiableValue<T> fromString(String string) {
                T value = supplier.apply(string);
                VerifiableValue.VerificationState verificationState = cell.getItem() == null ? VerifiableValue.VerificationState.UNVERIFIED : cell.getItem().getVerificationState() ;
                return new VerifiableValue<>(value, verificationState);
            }

        });

        ChangeListener<VerifiableValue.VerificationState> verifiedListener = (obs, oldState, newState) -> {
            if (newState == null || newState == VerifiableValue.VerificationState.UNVERIFIED) {
                cell.setStyle("");
            } else if (newState == VerifiableValue.VerificationState.VERIFIED) {
                cell.setStyle("-fx-background-color: yellow ;");
            } else if (newState == VerifiableValue.VerificationState.ERROR) {
                cell.setStyle("-fx-background-color: red ;");
            }
        };


        cell.itemProperty().addListener((obs, oldItem, newItem) -> {
            if (oldItem != null) {
                oldItem.verificationStateProperty().removeListener(verifiedListener);
            }
            if (newItem == null) {
                cell.setStyle("");
            } else {
                if (newItem.getVerificationState() == null || newItem.getVerificationState() == VerifiableValue.VerificationState.UNVERIFIED) {
                    cell.setStyle("");
                } else if (newItem.getVerificationState() == VerifiableValue.VerificationState.VERIFIED) {
                    cell.setStyle("-fx-background-color: yellow ;");
                } else if (newItem.getVerificationState() == VerifiableValue.VerificationState.ERROR) {
                    cell.setStyle("-fx-background-color: red ;");
                }               
                newItem.verificationStateProperty().addListener(verifiedListener);
            }
        });

        return cell ;
    }

    @Override
    public void start(Stage primaryStage) {
        TableView<Product> table = new TableView<>();
        table.getSelectionModel().setCellSelectionEnabled(true);
        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        table.setEditable(true);

        TableColumn<Product, String> productCol = new TableColumn<>("Product");
        productCol.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getName()));

        TableColumn<Product, VerifiableValue<Integer>> quantityColumn = new TableColumn<>("Quantity");
        quantityColumn.setCellValueFactory(cellData -> cellData.getValue().quantityProperty());

        quantityColumn.setCellFactory(tc -> createTableCell("%,d", Integer::new));

        TableColumn<Product, VerifiableValue<Double>> weightColumn = new TableColumn<>("Weight");
        weightColumn.setCellValueFactory(cellData -> cellData.getValue().weightProperty());

        weightColumn.setCellFactory(tc -> createTableCell("%.3f Kg", Double::new));

        table.getColumns().add(productCol);
        table.getColumns().add(quantityColumn);
        table.getColumns().add(weightColumn);

        Button verifySelected = new Button("Verify Selected");
        verifySelected.setOnAction(e -> {
            for (TablePosition<?, ?> pos : table.getSelectionModel().getSelectedCells()) {
                if (pos.getTableColumn() == quantityColumn) {
                    Product product = table.getItems().get(pos.getRow());
                    product.getQuantity().setVerificationState(VerifiableValue.VerificationState.VERIFIED);
                } else if (pos.getTableColumn() == weightColumn) {
                    Product product = table.getItems().get(pos.getRow());
                    product.getWeight().setVerificationState(VerifiableValue.VerificationState.VERIFIED);
                }
            }
        });
        verifySelected.disableProperty().bind(Bindings.isEmpty(table.getSelectionModel().getSelectedCells()));

        Button errorSelected = new Button("Mark all selected as error");
        errorSelected.setOnAction(e -> {
            for (TablePosition<?, ?> pos : table.getSelectionModel().getSelectedCells()) {
                if (pos.getTableColumn() == quantityColumn) {
                    Product product = table.getItems().get(pos.getRow());
                    product.getQuantity().setVerificationState(VerifiableValue.VerificationState.ERROR);
                } else if (pos.getTableColumn() == weightColumn) {
                    Product product = table.getItems().get(pos.getRow());
                    product.getWeight().setVerificationState(VerifiableValue.VerificationState.ERROR);
                }
            }
        });
        errorSelected.disableProperty().bind(Bindings.isEmpty(table.getSelectionModel().getSelectedCells()));


        Button unverifyAll = new Button("Remove all verification");
        unverifyAll.setOnAction(e -> {
            for (Product product : table.getItems()) {
                product.getQuantity().setVerificationState(VerifiableValue.VerificationState.UNVERIFIED);
                product.getWeight().setVerificationState(VerifiableValue.VerificationState.UNVERIFIED);
            }
        });

        HBox buttons = new HBox(5, verifySelected, errorSelected, unverifyAll);
        buttons.setAlignment(Pos.CENTER);
        buttons.setPadding(new Insets(5));

        // random data:
        Random rng = new Random();
        for (int i = 0 ;  i < 100; i++) {
            Product product = new Product("Item "+(i+1));
            product.setQuantity(new VerifiableValue<>(rng.nextInt(1200)));
            product.setWeight(new VerifiableValue<>(rng.nextDouble() * 1000));
            table.getItems().add(product);
        }

        BorderPane root = new BorderPane(table);
        root.setBottom(buttons);

        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }




    public static class Product {

        private ObjectProperty<VerifiableValue<Double>> weight = new SimpleObjectProperty<>();
        private ObjectProperty<VerifiableValue<Integer>> quantity = new SimpleObjectProperty<>();

        private final String name ;

        public Product(String name) {
            this.name = name ;
        }

        public String getName() {
            return name ;
        }

        public final ObjectProperty<VerifiableValue<Double>> weightProperty() {
            return this.weight;
        }

        public final CellHighlightingTable.VerifiableValue<java.lang.Double> getWeight() {
            return this.weightProperty().get();
        }

        public final void setWeight(final CellHighlightingTable.VerifiableValue<java.lang.Double> weight) {
            this.weightProperty().set(weight);
        }

        public final ObjectProperty<VerifiableValue<Integer>> quantityProperty() {
            return this.quantity;
        }

        public final CellHighlightingTable.VerifiableValue<java.lang.Integer> getQuantity() {
            return this.quantityProperty().get();
        }

        public final void setQuantity(final CellHighlightingTable.VerifiableValue<java.lang.Integer> quantity) {
            this.quantityProperty().set(quantity);
        }


    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.util.Random;
导入java.util.function.function;
导入javafx.application.application;
导入javafx.beans.binding.Bindings;
导入javafx.beans.property.ObjectProperty;
导入javafx.beans.property.SimpleObject属性;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.value.ChangeListener;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
import java.util.Random;
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class CellHighlightingTable extends Application {

    public static class VerifiableValue<T> {

        public enum VerificationState { UNVERIFIED, VERIFIED, ERROR }

        private final T value ;
        private final ObjectProperty<VerificationState> verificationState = new SimpleObjectProperty<>(VerificationState.UNVERIFIED) ;

        public VerifiableValue(T value) {
            this.value = value ;
        }

        public VerifiableValue(T value, VerificationState verificationState) {
            this(value);
            setVerificationState(verificationState);
        }



        public T getValue() {
            return value ;
        }

        public final ObjectProperty<VerificationState> verificationStateProperty() {
            return this.verificationState;
        }


        public final CellHighlightingTable.VerifiableValue.VerificationState getVerificationState() {
            return this.verificationStateProperty().get();
        }


        public final void setVerificationState(
                final CellHighlightingTable.VerifiableValue.VerificationState verificationState) {
            this.verificationStateProperty().set(verificationState);
        }


    }

    private <T> TableCell<Product, VerifiableValue<T>> createTableCell(String format, Function<String, T> supplier) {
        TextFieldTableCell<Product, VerifiableValue<T>> cell = new TextFieldTableCell<>();

        cell.setConverter(new StringConverter<VerifiableValue<T>>() {

            @Override
            public String toString(VerifiableValue<T> item) {
                return item == null ? "" : String.format(format, item.getValue());
            }

            @Override
            public VerifiableValue<T> fromString(String string) {
                T value = supplier.apply(string);
                VerifiableValue.VerificationState verificationState = cell.getItem() == null ? VerifiableValue.VerificationState.UNVERIFIED : cell.getItem().getVerificationState() ;
                return new VerifiableValue<>(value, verificationState);
            }

        });

        ChangeListener<VerifiableValue.VerificationState> verifiedListener = (obs, oldState, newState) -> {
            if (newState == null || newState == VerifiableValue.VerificationState.UNVERIFIED) {
                cell.setStyle("");
            } else if (newState == VerifiableValue.VerificationState.VERIFIED) {
                cell.setStyle("-fx-background-color: yellow ;");
            } else if (newState == VerifiableValue.VerificationState.ERROR) {
                cell.setStyle("-fx-background-color: red ;");
            }
        };


        cell.itemProperty().addListener((obs, oldItem, newItem) -> {
            if (oldItem != null) {
                oldItem.verificationStateProperty().removeListener(verifiedListener);
            }
            if (newItem == null) {
                cell.setStyle("");
            } else {
                if (newItem.getVerificationState() == null || newItem.getVerificationState() == VerifiableValue.VerificationState.UNVERIFIED) {
                    cell.setStyle("");
                } else if (newItem.getVerificationState() == VerifiableValue.VerificationState.VERIFIED) {
                    cell.setStyle("-fx-background-color: yellow ;");
                } else if (newItem.getVerificationState() == VerifiableValue.VerificationState.ERROR) {
                    cell.setStyle("-fx-background-color: red ;");
                }               
                newItem.verificationStateProperty().addListener(verifiedListener);
            }
        });

        return cell ;
    }

    @Override
    public void start(Stage primaryStage) {
        TableView<Product> table = new TableView<>();
        table.getSelectionModel().setCellSelectionEnabled(true);
        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        table.setEditable(true);

        TableColumn<Product, String> productCol = new TableColumn<>("Product");
        productCol.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getName()));

        TableColumn<Product, VerifiableValue<Integer>> quantityColumn = new TableColumn<>("Quantity");
        quantityColumn.setCellValueFactory(cellData -> cellData.getValue().quantityProperty());

        quantityColumn.setCellFactory(tc -> createTableCell("%,d", Integer::new));

        TableColumn<Product, VerifiableValue<Double>> weightColumn = new TableColumn<>("Weight");
        weightColumn.setCellValueFactory(cellData -> cellData.getValue().weightProperty());

        weightColumn.setCellFactory(tc -> createTableCell("%.3f Kg", Double::new));

        table.getColumns().add(productCol);
        table.getColumns().add(quantityColumn);
        table.getColumns().add(weightColumn);

        Button verifySelected = new Button("Verify Selected");
        verifySelected.setOnAction(e -> {
            for (TablePosition<?, ?> pos : table.getSelectionModel().getSelectedCells()) {
                if (pos.getTableColumn() == quantityColumn) {
                    Product product = table.getItems().get(pos.getRow());
                    product.getQuantity().setVerificationState(VerifiableValue.VerificationState.VERIFIED);
                } else if (pos.getTableColumn() == weightColumn) {
                    Product product = table.getItems().get(pos.getRow());
                    product.getWeight().setVerificationState(VerifiableValue.VerificationState.VERIFIED);
                }
            }
        });
        verifySelected.disableProperty().bind(Bindings.isEmpty(table.getSelectionModel().getSelectedCells()));

        Button errorSelected = new Button("Mark all selected as error");
        errorSelected.setOnAction(e -> {
            for (TablePosition<?, ?> pos : table.getSelectionModel().getSelectedCells()) {
                if (pos.getTableColumn() == quantityColumn) {
                    Product product = table.getItems().get(pos.getRow());
                    product.getQuantity().setVerificationState(VerifiableValue.VerificationState.ERROR);
                } else if (pos.getTableColumn() == weightColumn) {
                    Product product = table.getItems().get(pos.getRow());
                    product.getWeight().setVerificationState(VerifiableValue.VerificationState.ERROR);
                }
            }
        });
        errorSelected.disableProperty().bind(Bindings.isEmpty(table.getSelectionModel().getSelectedCells()));


        Button unverifyAll = new Button("Remove all verification");
        unverifyAll.setOnAction(e -> {
            for (Product product : table.getItems()) {
                product.getQuantity().setVerificationState(VerifiableValue.VerificationState.UNVERIFIED);
                product.getWeight().setVerificationState(VerifiableValue.VerificationState.UNVERIFIED);
            }
        });

        HBox buttons = new HBox(5, verifySelected, errorSelected, unverifyAll);
        buttons.setAlignment(Pos.CENTER);
        buttons.setPadding(new Insets(5));

        // random data:
        Random rng = new Random();
        for (int i = 0 ;  i < 100; i++) {
            Product product = new Product("Item "+(i+1));
            product.setQuantity(new VerifiableValue<>(rng.nextInt(1200)));
            product.setWeight(new VerifiableValue<>(rng.nextDouble() * 1000));
            table.getItems().add(product);
        }

        BorderPane root = new BorderPane(table);
        root.setBottom(buttons);

        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }




    public static class Product {

        private ObjectProperty<VerifiableValue<Double>> weight = new SimpleObjectProperty<>();
        private ObjectProperty<VerifiableValue<Integer>> quantity = new SimpleObjectProperty<>();

        private final String name ;

        public Product(String name) {
            this.name = name ;
        }

        public String getName() {
            return name ;
        }

        public final ObjectProperty<VerifiableValue<Double>> weightProperty() {
            return this.weight;
        }

        public final CellHighlightingTable.VerifiableValue<java.lang.Double> getWeight() {
            return this.weightProperty().get();
        }

        public final void setWeight(final CellHighlightingTable.VerifiableValue<java.lang.Double> weight) {
            this.weightProperty().set(weight);
        }

        public final ObjectProperty<VerifiableValue<Integer>> quantityProperty() {
            return this.quantity;
        }

        public final CellHighlightingTable.VerifiableValue<java.lang.Integer> getQuantity() {
            return this.quantityProperty().get();
        }

        public final void setQuantity(final CellHighlightingTable.VerifiableValue<java.lang.Integer> quantity) {
            this.quantityProperty().set(quantity);
        }


    }

    public static void main(String[] args) {
        launch(args);
    }
}