F.A F.A - 5 months ago 38
Java Question

Dynamically add CSS stylesheets in JavaFX

I would like to add a CSS file which is located somewhere on the filesystem.
The purpose is to write an application where the user can add JavaFX CSS files (which are created by anyone and located anywhere) dynamically.

I tried something like that, only for testing, to see if dynamically added CSS files works:

public class Main extends Application {

@Override
public void start(Stage primaryStage) throws Exception{
Label label = new Label("Hello");
Scene scene = new Scene(label);

//file would be set by an file chosser
File file = new File("C:/test.css");
scene.getStylesheets().add(file.getAbsolutePath());

primaryStage.setTitle("Title");
primaryStage.setScene(scene);
primaryStage.show();
}


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


But I get always the same error:

WARNING: com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged Resource "C:\test.css" not found.


How can I fix it?

Answer

Your problem is that you aren't using a URL. Here you can find more documentation on how the css are loaded and the css reference.

So if you put the string as a URL you could set the css dynamically with an external file like in this one:

public void start(Stage primaryStage) throws Exception {
    Button button = new Button("Change CSS");
    button.setOnAction(new EventHandler<ActionEvent>() {            
        @Override
        public void handle(ActionEvent arg0) {
            scene.getStylesheets().clear();
            String css = count++%2==0?"file:///C:/temp/a.css":"file:///C:/temp/b.css";
            System.out.println("Loading..." + css);
            scene.getStylesheets().add(css);
        }
    });     
    VBox vbox = new VBox(10);
    vbox.setAlignment(Pos.CENTER);
    vbox.getChildren().add(button);
    scene = new Scene(vbox, 200, 200);
    primaryStage.setTitle("Title");
    primaryStage.setScene(scene);
    primaryStage.show();
}

In the a.css

.button{    
-fx-text-fill: white;
-fx-background-color: red;}

And in b.css

.button{    
-fx-text-fill: white;
-fx-background-color: black;}

Hope it helps!