[英]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.