I am attempting to create a Pane object with JavaFX that has three different colors: A color for the background, a color for the text, and a color for the buttons. Each of these
I agree with the approach of what @Sedrick has mentioned in the comments.
If you want to change only colors without modifying the rest of CSS, you can follow the below approach as well. This can be quite useful if you have a very large css file that needs to be themed.
The basic idea is to have all your css is one base css file. Define all your colors as variables in .root class in that base file. And for each of your theme css, you just need to override the color variables only. And load the theme css file on top of base file. This way you will not encounter any possible copy-paste issues or missing css issues :)
A complete working example is below:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.stream.Stream;
public class DynamicStyling_Demo extends Application {
@Override
public void start(Stage stage) throws Exception {
VBox root = new VBox();
root.setAlignment(Pos.CENTER);
root.setSpacing(10);
Stream.of("Default", "Type1", "Type2", "Type3").forEach(type -> {
Button button = new Button("Open " + type);
button.setOnAction(e -> {
Stage subStage = buildStage(type);
subStage.initOwner(stage);
if (!type.equalsIgnoreCase("default")) {
subStage.getScene().getStylesheets().add(this.getClass().getResource(type.toLowerCase() + ".css").toExternalForm());
}
subStage.show();
});
root.getChildren().add(button);
});
Scene sc = new Scene(root, 400, 400);
sc.getStylesheets().add(this.getClass().getResource("base.css").toExternalForm());
stage.setScene(sc);
stage.show();
}
private Stage buildStage(String title) {
Label label = new Label("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
label.setWrapText(true);
VBox.setVgrow(label, Priority.ALWAYS);
Button btn = new Button("Sample Button");
VBox pane = new VBox(label, btn);
pane.getStyleClass().add("my-pane");
StackPane subRoot = new StackPane(pane);
subRoot.setPadding(new Insets(10));
Stage subStage = new Stage();
subStage.setTitle(title);
subStage.setScene(new Scene(subRoot, 300, 300));
subStage.getScene().getStylesheets().add(this.getClass().getResource("base.css").toExternalForm());
return subStage;
}
public static void main(String[] args) {
Application.launch(args);
}
}
base.css:
.root{
-fx-window-border: #444444;
-fx-window-color: #999999;
-fx-window-text: #111111;
-fx-button-color: #555555;
}
.my-pane{
-fx-border-width: 2px;
-fx-border-color: -fx-window-border;
-fx-background-color: -fx-window-color;
-fx-padding: 10px;
-fx-spacing: 10px;
}
.my-pane .label{
-fx-text-fill: -fx-window-text;
-fx-font-size: 16px;
}
.my-pane .button{
-fx-base: -fx-button-color;
}
type1.css:
.root{
-fx-window-border: red;
-fx-window-color: yellow;
-fx-window-text: brown;
-fx-button-color: pink;
}
type2.css:
.root{
-fx-window-border: green;
-fx-window-color: lightblue;
-fx-window-text: white;
-fx-button-color: grey;
}
type3.css:
.root{
-fx-window-border: brown;
-fx-window-color: lightgreen;
-fx-window-text: blue;
-fx-button-color: yellow;
}