A. Rohmann
A. Rohmann

Reputation: 101

JavaFX How to style tab close buttons programmatically

I need to style the close button of a javafx tab programmatically. Every of my tabs gets an individual color from a colorset enum.

myTab.setStyle("-fx-background-color:" + set.getBackgroundColor() + ";");

Some colors are dark and others are light, so I need to set different complementary colors for the tab close button like

myTab.getCloseButton().setStyle("-fx-background-color:" + set.getForegroundColor() + ";");

But I couldn't find a method to retrieve a handle to the close button of a tab.

Part of my CSS-File

.tab {
    -fx-background-insets: 0, 1, 2;
    -fx-background-radius: 0 0 0 0, 0 0 0 0, 0 0 0 0; /* eckig */
}
.tab .tab-close-button {
    -fx-shape: "M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z";
    -fx-scale-shape: false; 
}

I got it working using different id's for my tabs

myTab.setId("darktab");
myTab.setId("lighttab");

In conjunction with separate entries in my css-file

#darktab .tab-close-button { -fx-background-color: white; }
#lighttab .tab-close-button { -fx-background-color: black; }

But this is a bad solution because I need many complementary colors für all defined colors in my enum.

Did I miss something? Does anyone know how to get a handle on tab close buttons?

I have the same problem with Styling the dropdown button and of TabPanes

Upvotes: 3

Views: 2853

Answers (2)

selami tastan
selami tastan

Reputation: 92

This is very useful but sometimes you need to customize a little bit more. In order to do that, you need to modify your CSS.

/*******************************************************************************
 *                                                                             *
 * TabPane                                                                    *
 *                                                                             *
 ******************************************************************************/
.tab-pane {
    /*
    -fx-tab-min-width:120px;
    -fx-tab-max-width:120px;
    -fx-tab-min-height:50px;
    -fx-tab-max-height:50px;
     */
}

.tab {
    -fx-font-family: Segoe UI Symbol;
    -fx-font-size: 11;
    -fx-font-weight: regular;
    /*-fx-background-color:royalblue ;*/
}

.tab:selected {
    -fx-font-size: 11;
   /* -fx-font-weight: bold;    */
    /*-fx-background-color:blue ; */
}

.tab-close-button{
    -fx-background-image : null;
    -fx-background-size : 18;
    -fx-background-repeat : no-repeat;
    -fx-background-position : center;
    -fx-shape: null;
    -fx-background-color: transparent;
}
.tab-close-button:hover{
    -fx-background-image : url("/icons/icons8_multiply_100px_1.png");
    -fx-background-color: #DFE7D2
}

Upvotes: 0

James_D
James_D

Reputation: 209330

The way this is handled in the default style sheet (typically for text colors) is to use a looked-up-color (-fx-background) for the background color, and then a ladder function for the contrasting color.

The ladder function works by creating a color gradient based on the intensity of a provided color. So for example you could do:

.tab {
    -fx-background-insets: 0, 1, 2;
    -fx-background-radius: 0 0 0 0, 0 0 0 0, 0 0 0 0; /* eckig */
    -fx-background-color: tab-background ;
    tab-background: white ;
}
.tab .tab-close-button {
    -fx-shape: "M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z";
    -fx-scale-shape: false; 
    -fx-background-color: ladder(tab-background, white 49%, black 50%);
}

.tab .tab-label {
    -fx-text-fill: ladder(tab-background, white 49%, black 50%);
}

This defines a looked-up color called tab-background which applies to tabs and all child nodes, and sets the background of the tab to that color. Then the background of the tab close button is set to a color determined by the ladder function: if the intensity of tab-background is 49% or less, it is white; if it is 50% or more, it is black (and there's a gradient for the borderline cases in between). Note the same technique is used to make the text visible in the tab labels.

Now you can just do

myTab.setStyle("tab-background:" + set.getBackgroundColor() + ";");

and the tab close button will automatically select either white or black depending on the intensity of the tab background.

SSCCE (with the CSS file shown above as tab-background.css):

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

public class TabBackgroundTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        TabPane tabPane = new TabPane();
        Tab tab1 = new Tab("Tab 1");
        tab1.setStyle("tab-background: white;");
        Tab tab2 = new Tab("Tab 2");
        tab2.setStyle("tab-background: black;");
        tabPane.getTabs().addAll(tab1, tab2);
        Scene scene = new Scene(tabPane, 600, 600);
        scene.getStylesheets().add("tab-background.css");
        primaryStage.setScene(scene);
        primaryStage.show();

    }

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

Upvotes: 5

Related Questions