Search code examples
javafxbackgroundtableviewcelltablecell

JavaFX Set Cell Background Color of TableColumn


TableColumn tc = new TableColumn();

tc.getStyleClass.add(".style in css file")

I set up the TableColumn with a CSS file, and I want to give each cell different background colors. How can I accomplish this?

Example) TableColumn 1~5
TableColumn 1, row 3 has black and TableColumn 5, row 4 has green ... etc


Solution

  • 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;
    }