I'm working on JavaFX app that uses CSS styles that are included in file. What i want is to change CSS style after an action happens on button and i wrote some code that changes style of Button when i enter/exit it:

public void actionMouseEntered() {
    buttonReflex1.getStyleClass().clear();
    buttonReflex1.getStyleClass().add("button_reflex_pressed");
    }
public void actionMouseExited(){
    buttonReflex1.getStyleClass().clear();
    buttonReflex1.getStyleClass().add("button_reflex");
}

And here you have my CSS file:

.button_reflex{
    -fx-shape: "M 200 *a lot of numbers here* Z";
    -fx-background-color: radial-gradient(focus-angle 360deg, focus-distance 0%, center 50% 50%, radius 70%, reflect, lightblue, aqua 30%, blue);
    -fx-text-fill: linear-gradient(#e4e000 0%, #ff0000 50%, #e4e000 100%);
}
.button_reflex_pressed{
    -fx-shape: "M 200 *a lot of numbers here* Z";
    -fx-background-color: radial-gradient(focus-angle 360deg, focus-distance 0%, center 50% 50%, radius 70%, reflect, dodgerblue, deepskyblue 30%, darkblue);
    -fx-text-fill: linear-gradient(#e4e000 0%, #ff0000 50%, #e4e000 100%);
}

They differ in a color of buttons.

Code i wrote above WORKS, but i think i didn't write it in a good way. Could you tell me if my method of implementing it is correct, or if it isn't, please tell me how can i do it better, because i don't want to learn bad habits.

2 Answers

4
fabian On Best Solutions

You do not need to change the style class. Changing the style class also is not the way best way to approach this. A PseudoClass should be used in this case. Also you should avoid duplicating css properties that do not differ or differ only in colors. Use a rule for both to specify this only once making it easier to modify; in the latter case you can use lookedup colors:

private static final PseudoClass MY_HOVER = PseudoClass.getPseudoClass("my-hover");

...
buttonReflex1.getStyleClass().setAll("button-reflex");
...

    boolean hovering = ...;
    buttonReflex1.pseudoClassStateChanged(MY_HOVER, hovering);
.button-reflex {
    -fx-background-color1: lightblue;
    -fx-background-color2: aqua;
    -fx-background-color3: blue;
    -fx-shape: "M 200 *a lot of numbers here* Z";
    -fx-background-color: radial-gradient(focus-angle 360deg, focus-distance 0%, center 50% 50%, radius 70%, reflect, -fx-background-color1, -fx-background-color2 30%, -fx-background-color3);
    -fx-text-fill: linear-gradient(#e4e000 0%, #ff0000 50%, #e4e000 100%);
}

.button-reflex:my-hover {
    /* only change colors here; keep the rest */
    -fx-background-color1: dodgerblue;
    -fx-background-color2: deepskyblue;
    -fx-background-color3: darkblue;
}

Note: The my-hover pseudoclass is only used here to demonstrate the general approach. JavaFX Nodes provide some pseudoclasses by default which should be used instead: hover, pressed, ect...

See JavaFX CSS Reference Guide: Node

1
Community On

So first off all yes you can change the CSS while run time.

But you are using it in a wrong way.

So if you have your base CSS class for your Node. For example:

.button {
    -fx-background-color: red;
}

and now if you want to have an effect for any JavaFx Event than there are some options like Hover, Pressed, Focused ...

.button {
   -fx-background-color: red;
}

.button:hover {
   -fx-background-color: blue;
}

.button:pressed{
   -fx-background-color: green;
}

JavaFx is than handling everything for you and you dont have to change the style manually.