javafx 在运行时更改 css
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17769388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javafx change css at runtime
提问by Rob
Is it possible to change css for a JavaFX application while it is running?
是否可以在运行时更改 JavaFX 应用程序的 css?
The effect I am looking for is changing skins or themes at the click of a button.
我正在寻找的效果是单击按钮即可更改皮肤或主题。
The UI is in an FXML
file if that makes any difference.
FXML
如果这有什么不同,UI 在一个文件中。
I have tried
我试过了
Scene.getStylesheets()
.add(getClass().getResource(skinFileName).toExternalForm());
which has no effect.
这没有效果。
thanks
谢谢
回答by Uluk Biy
It should have the effect. Try this full demo code:
应该有效果。试试这个完整的演示代码:
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);
}
}
theme1 css:
主题 1 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;
}
theme2 css:
主题2 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;
}
Note the same named CSS selectors in both theme1 and theme2 css files.
请注意 theme1 和 theme2 css 文件中名称相同的 CSS 选择器。
回答by Dassi Orleando
You can also try this piece of code(simple and truly illustrative) :
您也可以尝试这段代码(简单且真正具有说明性):
- A Container for it: I chose BorderPane.
- Add a main Scene for your application.
- A Menu Bar with a set of items depending on the look of your application.
- And item on the Menu bar.
- 一个容器:我选择了 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();
Supposed that you have your two CSS files in the folder of the class where you will call this code with the corresponding name theme1.css and theme2.css.
Now you can switch between two themes while your application is running.
假设您在类的文件夹中有两个 CSS 文件,您将在其中使用相应的名称 theme1.css 和 theme2.css 调用此代码。
现在,您可以在应用程序运行时在两个主题之间切换。