簡體   English   中英

JavaFX CSS動態樣式

[英]JavaFX CSS Dynamic Styling

在詢問之前,我在網上搜索並搜索了我的問題的答案,但找不到這樣的東西。

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

FX中此類事情的“最佳實踐”是什么?

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

  • -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實例,並將所有根節點的styleProperty綁定到cssProperty 或者,您可以向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());

等,當用戶選擇新顏色時,一切都會更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM