実行中にJavaFXアプリケーションのcssを変更することは可能ですか?
私が探している効果は、ボタンをクリックするだけでスキンやテーマを変更することです。
違いが生じる場合、UIはFXML
ファイルにあります。
私が試してみました
Scene.getStylesheets()
.add(getClass().getResource(skinFileName).toExternalForm());
効果はありません。
ありがとう
効果があるはずです。この完全なデモコードを試してください:
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:
.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:
.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;
}
Theme1ファイルとtheme2cssファイルの両方で同じ名前のCSSセレクターに注意してください。
このコードを試すこともできます(シンプルで本当に説明的です):
- そのためのコンテナ: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();
クラスのフォルダーに2つのCSSファイルがあり、対応する名前theme1.cssおよびtheme2.cssでこのコードを呼び出すとします。
これで、アプリケーションの実行中に2つのテーマを切り替えることができます。