MSOUFAN
MSOUFAN

Reputation: 101

JavaFx list View coloring the list cell

I have a list view of Labels and I want to color the list cells on run time. The problem is that I want to fill the entire Cell with the color not only the background of the Label. Is there way to do it in Java/CSS?

Upvotes: 1

Views: 9448

Answers (2)

user1300214
user1300214

Reputation:

In your cell factory's updateItem function, just use the following lines:

if(getIndex() % 2 == 1)
    setStyle("-fx-background-color: #AAAAAA");
else
    setStyle("");

Upvotes: 1

jewelsea
jewelsea

Reputation: 159281

Understanding the dynamic nature of ListView cell coloring

Normally, the inner cell color changes based upon a number of things:

  1. Whether the cell is an odd or even row (even rows have a lighter background).
  2. Whether the row is selected.
  3. Selected rows have different colors depending upon whether the control has focus or not (a focused selected row is blue, an unfocused selected row is gray).

So because the cell color can change based upon the state, you need to decide if you want to retain this behavior or not when you set custom coloring for your cells.

Sample Solution

Here is an example which will set the cell color to a pale green color depending upon whether a list item matches a criteria (in this case hardcoded for testing purposes to a name beginning with the letter 'J').

sample

import javafx.application.Application;
import javafx.collections.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ColoredList extends Application {
    private static final ObservableList<String> data = FXCollections.observableArrayList(
            "Jill",
            "Jack",
            "Tom",
            "Harry",
            "Jenney"
    );

    private static final String DEFAULT_CONTROL_INNER_BACKGROUND = "derive(-fx-base,80%)";
    private static final String HIGHLIGHTED_CONTROL_INNER_BACKGROUND = "derive(palegreen, 50%)";

    @Override
    public void start(Stage stage) throws Exception {
        ListView<String> listView = new ListView<>(data);
        listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
            @Override
            public ListCell<String> call(ListView<String> param) {
                return new ListCell<String>() {
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);

                        if (item == null || empty) {
                            setText(null);
                            setStyle("-fx-control-inner-background: " + DEFAULT_CONTROL_INNER_BACKGROUND + ";");
                        } else {
                            setText(item);
                            if (item.startsWith("J")) {
                                setStyle("-fx-control-inner-background: " + HIGHLIGHTED_CONTROL_INNER_BACKGROUND + ";");
                            } else {
                                setStyle("-fx-control-inner-background: " + DEFAULT_CONTROL_INNER_BACKGROUND + ";");
                            }
                        }
                    }
                };
            }
        });

        VBox layout = new VBox(listView);
        layout.setPadding(new Insets(10));

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

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

Some things to note:

  1. The custom cell rendering is accomplished via a custom cell factory for the ListView.
  2. The cells returned by the cell factory, set the -fx-control-inner-background looked-up CSS color depending upon the cell state. If you don't know what a looked-up color is, look it up in the the JavaFX CSS reference guide and look at the modena.css file in the jfxrt.jar file that ships with your Java install.
  3. The default cell rendering mechanism will slightly darken or lighten even and odd rows in the ListView, even based upon your custom color.
  4. The sample only sets custom colors for non-selected rows. For selected rows, the default blue and gray colors are retained. So the sample is not comprehensive, but hopefully provides enough information for you to accomplish what you want.
  5. The sample codes the default and custom colors in code, but a larger app would be better off having these defined in a separate user CSS stylesheet.

Upvotes: 8

Related Questions