0

https://stackoverflow.com/a/10615258/529411

I would like to add a background color to my tabpane dynamically (depending on certain conditions). How can I achieve this from code? One option is to assign he tab a specific ID which has the associated CSS, but in my case the color can be dynamically chosen by the user.

Also, I'm curious how to apply the styles in code when dealing with a hierarchy of components.

Community
  • 1
  • 1
Darth Ninja
  • 1,049
  • 2
  • 11
  • 34

1 Answers1

2

You can assign the background color to be a looked-up color in the CSS file:

.tab-pane > .tab-header-area > .tab-header-background {
    -fx-background-color: -fx-outer-border, -fx-text-box-border, my-tab-header-background ;
}

Now in code you can set the value of the looked-up color whenever you need to:

tabPane.setStyle("my-tab-header-background: blue ;");

SSCCE:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;

public class DynamicTabHeaderBackground extends Application {

    private static final String TAB_HEADER_BACKGROUND_KEY = "my-tab-header-background" ;

    @Override
    public void start(Stage primaryStage) {
        TabPane tabPane = new TabPane();
        tabPane.setStyle(TAB_HEADER_BACKGROUND_KEY+": blue ;");
        tabPane.getTabs().addAll(new Tab("Tab 1"), new Tab("Tab 2"));
        tabPane.getSelectionModel().selectedIndexProperty().addListener((obs, oldIndex, newIndex) -> {
            if (newIndex.intValue() == 0) {
                tabPane.setStyle(TAB_HEADER_BACKGROUND_KEY+": blue ;");
            } else {
                tabPane.setStyle(TAB_HEADER_BACKGROUND_KEY+": green ;");
            }
        });

        Scene scene = new Scene(tabPane, 400, 400);
        scene.getStylesheets().add("dynamic-tab-header.css");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

with dynamic-tab-header.css containing the CSS code above.

Update

If you have multiple tab panes, you might want to consider the following variant of the CSS file:

.tab-pane {
    my-tab-header-background: derive(-fx-text-box-border, 30%) ;
}

.tab-pane > .tab-header-area > .tab-header-background {
    -fx-background-color: -fx-outer-border, -fx-text-box-border, 
        linear-gradient(from 0px 0px to 0px 5px, -fx-text-box-border, my-tab-header-background) ;
}

This basically emulates the default behavior, but allows you to modify the background on any particular tab pane by calling the tabPane.setStyle(...) code as before.

James_D
  • 201,275
  • 16
  • 291
  • 322
  • Thanks, changed it to `#mytabpaneID > .tab-header....` so that the style is applied only to the tabpane I'm interested in. Otherwise it applies the style to all tab panes. – Darth Ninja Nov 25 '15 at 04:01
  • Yes, or see the alternative in the update, which gives you full flexibility to modify any or all of the tab panes with the same Java code. – James_D Nov 25 '15 at 04:12