2017-03-01 125 views
1

我在搜索和搜索我的問題的答案之前詢問,但找不到像這樣的東西。JavaFX CSS動態樣式

我希望我的應用程序用戶能夠從JavaFX ColorPicker中選擇一種顏色,並根據他們的選擇來選擇整個應用程序窗口的顏色,按鈕顏色,字體等。在我的應用程序中有很多屏幕,我並不是真的想在每個窗格上設置setStyle()以確保顏色更改我想要某種類型的CSS文件,其中的顏色可以根據所選的顏色進行更改在ColorPicker中。這可能嗎?我的意思是我意識到你可以通過Java代碼編寫一個文本文件,並給它一個「.css」擴展名,但是有沒有其他方法可以實現這一點?

什麼是在FX這種事情的「最佳實踐」?

+0

https://www.google.fr/search?q=javafx+theme&gws_rd=cr,ssl&ei=2S23WNWfBYrZU_O1hpgG – Aubin

回答

3

有一些顏色的一切都在摩德納基礎。我有一個例子的地方,這是我現在不能找到,但基本上

  • -fx-base
  • -fx-accent
  • -fx-default-button
  • -fx-focus-color
  • -fx-faint-focus-color(同-fx-focus-color但爲0x22的不透明度)

因此設置這些在根節點上基本上主題整個根和它的後代。

最終,當用戶在每個根節點上更改它們時,您將不得不以某種方式更新這些事實,並且您需要提供接線來完成此操作。使用CSS文件可能不是一種方法,因爲要確保更新的文件根據需要被重新加載將很困難。我可能會把事情聯繫起來,以便在用戶更改它們時,根節點的styleProperty()將更改爲定義這些顏色。

你可以考慮創建一個Theme類,它封裝這些:

public class Theme { 

    private final ObjectProperty<Color> base = new SimpleObjectProperty<>(Color.web("#ececec")); 
    private final ObjectProperty<Color> accent = new SimpleObjectProperty<>(Color.web("#0096c9")); 
    private final ObjectProperty<Color> defaultButton = new SimpleObjectProperty<>(Color.web("#abd8ed")); 
    private final ObjectProperty<Color> focusColor = new SimpleObjectProperty<>(Color.web("#039ed3")); 
    private final ObjectProperty<Color> faintFocusColor = new SimpleObjectProperty<>(Color.web("039ed322")); 

    public ObjectProperty<Color> baseProperty() { 
     return base ; 
    } 

    public final Color getBase() { 
     return baseProperty().get(); 
    } 

    public final void setBase(Color base) { 
     baseProperty().set(base); 
    } 

    // etc etc 

    private final ReadOnlyStringWrapper css = new ReadOnlyStringWrapper() ; 

    public Theme() { 
     css.bind(Bindings.createStringBinding(() -> String.format(
      "-fx-base: %s; " 
      +"-fx-accent: %s; " 
      +"-fx-default-button: %s; " 
      +"-fx-focus-color: %s ; " 
      +"-fx-faint-focus-color: %s ;", 
      toRgba(getBase()), 
      toRgba(getAccent()), 
      toRgba(getDefaultButton()), 
      toRgba(getFocusColor()), 
      toRgba(getFaintFocusColor())), 
      base, accent, defaultButton, focusColor, faintFocusColor)); 
    } 

    private String toRgba(Color color) { 
     int r = (int) (255 * color.getRed()); 
     int g = (int) (255 * color.getGreen()); 
     int b = (int) (255 * color.getBlue()); 
     int a = (int) (255 * color.getOpacity()); 
     return String.format("#%02x%02x%02x%02x", r, g, b, a); 
    } 

    public ReadOnlyStringProperty cssProperty() { 
     return css.getReadOnlyProperty(); 
    } 

} 

然後,你可以創建一個單一的Theme實例,你提供給你的應用程序,並綁定所有的根節點的stylePropertycssProperty。或者,也可以增加一個工廠方法來Theme用於產生根節點:

public <T extends Parent> T createThemedNode(Supplier<T> factory) { 
    T node = factory.get(); 
    node.styleProperty().bind(cssProperty()); 
    return node ; 
} 

您作爲使用,例如,

BorderPane root = theme.createThemedNode(BorderPane::new); 

如果使用FXML可以創建類似類型的工廠方法用於裝載一個FXML文檔並綁定結果節點的樣式。

最後,當然,你只需做一些像

ColorPicker baseColorPicker = new ColorPicker(); 
baseColorPicker.valueProperty().bindBidirectional(theme.baseProperty()); 

等,當用戶選擇一個新的色彩,一切都將被更新。

+0

您還可以查看「Caspian。css'如果你想看到使用的確切樣式表是默認的。這裏是一個鏈接:https://gist.github.com/tmazeika/c90c03c645d18722ddb0 – Chris

+0

默認的樣式表一直是Modena,而不是Caspian,現在已經有一段時間了。當我回到電腦時,我會發佈一個鏈接。 –

+1

我不好,你說得對。這裏是摩德納:https://gist.github.com/maxd/63691840fc372f22f470 – Chris