JavaFX Set Cell Background Color of TableColumn

心不动则不痛 提交于 2019-12-04 21:21:02

Create a cellFactory that selects the background color based on the column & row index.

Example:

TableView<Item<String>> tableView = new TableView<>();
// sample item class contains a single property with the same type as the type parameter (String in this case)
tableView.getItems().addAll(
        new Item<>("1"),
        new Item<>("2"),
        new Item<>("4"),
        new Item<>("5"),
        new Item<>("6"),
        new Item<>("7"),
        new Item<>("8"),
        new Item<>("9")
);

// create columns
TableColumn<Item<String>, String> column1 = new TableColumn<>("value");
TableColumn<Item<String>, Void> column2 = new TableColumn<>();
tableView.getColumns().addAll(column1, column2);

// create list of colors (CSS)
final List<String> colors = Arrays.asList(
        "blue",
        "green",
        "red",
        "violet",
        "yellow",
        ...
);

Callback factory = new Callback<TableColumn<Item<String>, Object>, TableCell<Item<String>, Object>>() {

    private int columns = tableView.getColumns().size();

    @Override
    public TableCell<Item<String>, Object> call(TableColumn<Item<String>, Object> param) {
        return new TableCell<Item<String>, Object>() {

            private int columnIndex = param.getTableView().getColumns().indexOf(param);

            @Override
            public void updateIndex(int i) {
                super.updateIndex(i);
                // select color based on index of row/column
                if (i >= 0) {
                    // select color repeating the color, if we run out of colors
                    String color = colors.get((i * columns + columnIndex) % colors.size());
                    this.setStyle("-fx-my-cell-background: " + color + ";");
                    System.out.println(getStyle());
                }
            }

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

                // assign item's toString value as text
                if (empty || item == null) {
                    setText(null);
                } else {
                    setText(item.toString());
                }
            }

        };
    }

};

column1.setCellValueFactory(new PropertyValueFactory<>("value"));
column1.setCellFactory(factory);
column2.setCellFactory(factory);

Scene scene = new Scene(tableView);
scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());

Valid CSS color strings are described here: https://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html#typecolor

style.css

.table-cell:filled {
    -fx-background-color: -fx-my-cell-background;
}

.table-view:row-selection .table-row-cell:selected .table-cell {
    -fx-background-color: null;
}

.table-view:cell-selection .table-cell:selected {
    -fx-background-color: -fx-table-cell-border-color, -fx-background;
}

To change the behavior of specific cells in a TableView you need can set the cellFactory of the TableColumns. Here's an example:

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;

public class TableMCVE extends Application {
    @Override
    public void start(Stage stage) {

        ObservableList<ObservableList<String>> tableData = FXCollections.observableArrayList();
        tableData.add(FXCollections.observableArrayList("Row1Col1", "Row1Col2"));
        tableData.add(FXCollections.observableArrayList("Row2Col1", "Row2Col2"));
        tableData.add(FXCollections.observableArrayList("Row3Col1", "Row3Col2"));

        TableView<ObservableList<String>> table = new TableView<ObservableList<String>>();

        TableColumn<ObservableList<String>, String> col1 = new TableColumn<ObservableList<String>, String>("Col1");
        col1.setCellValueFactory(e -> new SimpleStringProperty(e.getValue().get(0)));

        // Set the cell factory of the column with a custom TableCell to modify its behavior.
        col1.setCellFactory(e -> new TableCell<ObservableList<String>, String>() {
            @Override
            public void updateItem(String item, boolean empty) {
                // Always invoke super constructor.
                super.updateItem(item, empty);

                if (item == null || empty) {
                    setText(null);
                } else {
                    setText(item);

                    // If index is two we set the background color explicitly.
                    if (getIndex() == 2) {
                        this.setStyle("-fx-background-color: green;");
                    }
                }
            }
        });

        TableColumn<ObservableList<String>, String> col2 = new TableColumn<ObservableList<String>, String>("Col2");
        col2.setCellValueFactory(e -> new SimpleStringProperty(e.getValue().get(1)));

        // Set the cell factory of the column with a custom TableCell to modify its behavior.
        col2.setCellFactory(e -> new TableCell<ObservableList<String>, String>() {
            @Override
            public void updateItem(String item, boolean empty) {
                // Always invoke super constructor.
                super.updateItem(item, empty);

                if (item == null || empty) {
                    setText(null);
                } else {
                    setText(item);

                    // If index is zero we set the background color explicitly.
                    if (getIndex() == 0) {
                        this.setStyle("-fx-background-color: blue;");
                    }
                }
            }
        });

        table.getColumns().addAll(col1, col2);
        table.getItems().addAll(tableData);

        stage.setScene(new Scene(table));
        stage.show();
    }

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

In my example I just set the color based on the index the cell, but you can change that to something a little more meaningful obviously. E.g. the color could be based on the value of the cell.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!