2013-07-21 5 views
10

Ist es möglich, css für eine JavaFX-Anwendung zu ändern, während sie läuft?javafx change css zur Laufzeit

Der Effekt, nach dem ich suche, ist das Ändern von Skins oder Designs auf Knopfdruck.

Die Benutzeroberfläche befindet sich in einer FXML Datei, wenn dies einen Unterschied macht.

Ich habe

versucht
Scene.getStylesheets() 
    .add(getClass().getResource(skinFileName).toExternalForm()); 

die keine Wirkung hat.

danke

Antwort

9

Es sollte die Wirkung haben. Versuchen Sie, diese vollständige 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:

.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; 
} 

Beachten Sie die gleichnamigen CSS-Selektoren in beiden theme1 und theme2 CSS-Dateien.

2

Sie können auch dieses Stück Code versuchen (einfach und wirklich illustrativ):

  • Ein Container für sie: Ich BorderPane wählte.
  • Fügen Sie eine Hauptszene für Ihre Anwendung hinzu.
  • Eine Menüleiste mit einer Reihe von Elementen, die vom Aussehen Ihrer Anwendung abhängen.
  • Und Element in der Menüleiste.
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(); 

Vermeintliche, dass Sie Ihre zwei CSS-Dateien in dem Ordner, der Klasse haben , wo Sie diesen Code mit dem entsprechenden Namen theme1.css und theme2.css nennen.

Jetzt können Sie zwischen zwei Themen wechseln, während Ihre Anwendung läuft.