Christian T
Christian T

Reputation: 23

JavaFx DatePicker color single cell

Good evening everyone, I want to change the color of a special cell in the DatePicker of JavaFX. My aim is to change the color of the cell: 30th Jan. 2017.

I'm still learning how to use JavaFX so please be forbearing.

Best regards Christian Taeumel

Upvotes: 1

Views: 3430

Answers (1)

jewelsea
jewelsea

Reputation: 159576

Use a DateCellFactory:

ware

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Stage;
import javafx.util.Callback;

import java.time.LocalDate;
import java.time.MonthDay;

public class ColoredPick extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() {
            public DateCell call(final DatePicker datePicker) {
                return new DateCell() {
                    @Override public void updateItem(LocalDate item, boolean empty) {
                        super.updateItem(item, empty);

                        if (MonthDay.from(item).equals(MonthDay.of(3, 15)) &&
                            !(getStyleClass().contains("next-month") || getStyleClass().contains("previous-month"))
                            ) {
                            setTooltip(new Tooltip("Beware the Ides of March!"));
                            setStyle("-fx-background-color: #ff4444;");
                        } else {
                            setTooltip(null);
                            setStyle(null);
                        }
                    }
                };
            }
        };

        DatePicker picker = new DatePicker();
        picker.setDayCellFactory(dayCellFactory);

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

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

While the simple background style setting in code demonstrated above works fine in most cases, it would probably best to add and remove style classes as appropriate in the update method, rather than directly setting styles (so that the styles could be customized in CSS). Doing this would make it easier to customize the style of various potential states of the cell (e.g. selected or focused, etc).

Full CSS rules for customizing the various cell pseudo-states (e.g. :selected, :hover, :focused, etc.) can be found in modena.css which will be included in your JavaFX distribution (for JavaFX 8 it is inside jfxrt.jar). A selection from a Java 9 distribution is shown below. As you can see there is quite a bit of customization you can do in CSS and the potential combination of different states can make it a little tricky to correctly customize all of them:

.date-picker-popup > * > .date-cell {
    -fx-background-color: transparent;
    -fx-background-insets: 1, 2;
    -fx-padding: 0;
    -fx-alignment: BASELINE_CENTER;
    -fx-opacity: 1.0;
}
.date-picker-popup > * > .day-name-cell,
.date-picker-popup > * > .week-number-cell {
    -fx-font-size: 0.916667em;
}
.date-picker-popup > * > .week-number-cell {
    -fx-padding: 0.333333em 0.583333em 0.333333em 0.583333em; /* 4 7 4 7 */
    -fx-border-color: -fx-control-inner-background;
    -fx-border-width: 1px;
    -fx-background: -fx-control-inner-background;
    -fx-background-color: -fx-background;
    -fx-text-fill: -fx-accent;
}
.date-picker-popup > * > .day-cell {
    -fx-padding: 0.333333em 0.583333em 0.333333em 0.583333em; /* 4 7 4 7 */
    -fx-border-color: derive(-fx-selection-bar-non-focused, 60%);
    -fx-border-width: 1px;
    -fx-font-size: 1em;
    -fx-background: -fx-control-inner-background;
    -fx-background-color: -fx-background;
    -fx-text-fill: -fx-text-background-color;
}
.date-picker-popup > * > .hijrah-day-cell {
    -fx-alignment: TOP_LEFT;
    -fx-padding: 0.083333em 0.333333em 0.083333em 0.333333em; /* 1 4 1 4 */
    -fx-cell-size: 2.75em;
}
.date-picker-popup > * > .day-cell > .secondary-text {
    -fx-fill: #f3622d;
}
.date-picker-popup > * > .today {
    -fx-background-color: -fx-control-inner-background, derive(-fx-selection-bar-non-focused, -20%), -fx-control-inner-background;
    -fx-background-insets: 1, 2, 3;
}
.date-picker-popup > * > .day-cell:hover,
.date-picker-popup > * > .selected,
.date-picker-popup > * > .previous-month.selected,
.date-picker-popup > * > .next-month.selected {
    -fx-background: -fx-selection-bar;
}
.date-picker-popup > * > .previous-month:hover,
.date-picker-popup > * > .next-month:hover {
    -fx-background: -fx-selection-bar-non-focused;
}
.date-picker-popup > * > .today:hover,
.date-picker-popup > * > .today.selected {
    -fx-background-color: -fx-selection-bar, derive(-fx-selection-bar-non-focused, -20%),-fx-selection-bar;
}
.date-picker-popup > * > .day-cell:focused,
.date-picker-popup > * > .today:focused {
    -fx-background-color: -fx-control-inner-background, -fx-cell-focus-inner-border, -fx-control-inner-background;
    -fx-background-insets: 1, 2, 3;
}
.date-picker-popup > * > .day-cell:focused:hover,
.date-picker-popup > * > .today:focused:hover,
.date-picker-popup > * > .selected:focused,
.date-picker-popup > * > .today.selected:focused {
    -fx-background-color: -fx-selection-bar, -fx-cell-focus-inner-border, -fx-selection-bar;
}
.date-picker-popup > * > .previous-month,
.date-picker-popup > * > .next-month {
    -fx-background: derive(-fx-control-inner-background, -4%);
}
.date-picker-popup > * > .day-cell:hover > .secondary-text,
.date-picker-popup > * > .previous-month > .secondary-text,
.date-picker-popup > * > .next-month > .secondary-text,
.date-picker-popup > * > .selected > .secondary-text {
    -fx-fill: -fx-text-background-color;
}
.date-picker-popup > * > .previous-month.today,
.date-picker-popup > * > .next-month.today {
    -fx-background-color: derive(-fx-control-inner-background, -4%), derive(-fx-selection-bar-non-focused, -20%), derive(-fx-control-inner-background, -4%);
}

.date-picker-popup > * > .previous-month.today:hover,
.date-picker-popup > * > .next-month.today:hover {
    -fx-background-color: -fx-selection-bar-non-focused, derive(-fx-selection-bar-non-focused, -20%), -fx-selection-bar-non-focused;
}

Upvotes: 2

Related Questions