javafx在运行时更改css

Rob*_*Rob 10 css javafx javafx-2 fxml

是否可以在JavaFX应用程序运行时更改css?

我正在寻找的效果是点击一个按钮改变皮肤或主题.

FXML如果存在任何差异,则UI位于文件中.

我试过了

Scene.getStylesheets()
  .add(getClass().getResource(skinFileName).toExternalForm()); 
Run Code Online (Sandbox Code Playgroud)

这没有效果.

谢谢

Ulu*_*Biy 11

它应该有效果.试试这个完整的演示代码:

public class CssThemeDemo extends Application {

    private String theme1Url = getClass().getResource("theme1.css").toExternalForm();
    private String theme2Url = getClass().getResource("theme2.css").toExternalForm();

    @Override
    public void start(Stage primaryStage) {
        StackPane root = new StackPane();
        final Scene scene = new Scene(root, 300, 250);
        System.out.println("scene stylesheets: " + scene.getStylesheets());
        scene.getStylesheets().add(theme1Url);
        System.out.println("scene stylesheets: " + scene.getStylesheets());

        final Button btn = new Button("Load Theme 1");
        btn.getStyleClass().add("buttonStyle");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                scene.getStylesheets().remove(theme2Url);
                System.out.println("scene stylesheets on button 1 click: " + scene.getStylesheets());
                if(!scene.getStylesheets().contains(theme1Url)) scene.getStylesheets().add(theme1Url);
                System.out.println("scene stylesheets on button 1 click: " + scene.getStylesheets());
            }
        });

        final Button btn2 = new Button("Load Theme 2");
        btn2.getStyleClass().add("buttonStyle");
        btn2.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                scene.getStylesheets().remove(theme1Url);
                System.out.println("scene stylesheets on button 2 click: " + scene.getStylesheets());
                if(!scene.getStylesheets().contains(theme2Url)) scene.getStylesheets().add(theme2Url);
                System.out.println("scene stylesheets on button 2 click: " + scene.getStylesheets());
            }
        });

        ComboBox<String> comboBox = new ComboBox<String>(FXCollections.observableArrayList("Just", "another", "control"));
        root.getChildren().add(VBoxBuilder.create().spacing(10).children(btn, btn2, comboBox).build());

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

theme1 css:

.root{
    -fx-font-size: 14pt;
    -fx-font-family: "Tahoma";
    -fx-base: #DFB951;
    -fx-background: #A78732;
    -fx-focus-color: #B6A678;
}

.buttonStyle {
    -fx-text-fill: #006464;
    -fx-background-color: #DFB951;
    -fx-border-radius: 20;
    -fx-background-radius: 20;
    -fx-padding: 5;
}
Run Code Online (Sandbox Code Playgroud)

theme2 css:

.root{
    -fx-font-size: 16pt;
    -fx-font-family: "Courier New";
    -fx-base: rgb(132, 145, 47);
    -fx-background: rgb(225, 228, 203);
}

.buttonStyle {
    -fx-text-fill: red;
    -fx-background-color: lightcyan;
    -fx-border-color: green;
    -fx-border-radius: 5;
    -fx-padding: 3 6 6 6;
}
Run Code Online (Sandbox Code Playgroud)

请注意theme1和theme2 css文件中相同的命名CSS选择器.


Das*_*ndo 6

您也可以尝试这段代码(简单且真正具有说明性):

  • 一个容器:我选择了 BorderPane。
  • 为您的应用程序添加一个主场景。
  • 带有一组项目的菜单栏,具体取决于您的应用程序的外观。
  • 和菜单栏上的项目。
BorderPane rootPane = new BorderPane();
Parent content = FXMLLoader.load(getClass().getResource("sample.fxml"));
rootPane.setCenter(content);
Scene scene = new Scene(root, 650, 550, Color.WHITE);
// Menu bar
MenuBar menuBar = new MenuBar();

// file menu
Menu fileMenu = new Menu("_File");
MenuItem exitItem = new MenuItem("Exit");
exitItem.setAccelerator(new KeyCodeCombination(KeyCode.X, KeyCombination.SHORTCUT_DOWN));
exitItem.setOnAction(ae -> Platform.exit());

fileMenu.getItems().add(exitItem);
menuBar.getMenus().add(fileMenu);

// Look and feel menu
Menu themeMenu = new Menu("_Theme");
themeMenu.setMnemonicParsing(true);
menuBar.getMenus().add(themeMenu);
rootPane.setTop(menuBar);


MenuItem theme1 = new MenuItem("Theme 1");
theme1.setOnAction(ae -> {
            scene.getStylesheets().clear();
            setUserAgentStylesheet(null);
            scene.getStylesheets()
                    .add(getClass()
                            .getResource("theme1.css")
                            .toExternalForm());
});

MenuItem theme2 = new MenuItem("Theme 2");
        theme2.setOnAction(ae -> {
            scene.getStylesheets().clear();
            setUserAgentStylesheet(null);
            scene.getStylesheets()
                    .add(getClass()
                            .getResource("theme2.css")
                            .toExternalForm());
});


themeMenu.getItems()
                .addAll(theme1,
                        theme2);

primaryStage.setScene(scene);
primaryStage.show();
Run Code Online (Sandbox Code Playgroud)

假设您在类的文件夹中有两个 CSS 文件,您将在其中使用相应的名称 theme1.css 和 theme2.css 调用此代码。

现在,您可以在应用程序运行时在两个主题之间切换。