2017-03-01 10 views
1

質問する前にオンラインで質問を検索して検索しましたが、このようなものは見つかりませんでした。JavaFX CSS Dynamic Styling

アプリケーションのユーザーが、JavaFX ColorPickerから色を選択し、アプリケーションウィンドウの色、ボタンの色、フォントなどの選択肢を、その選択に基づいて変更できるようにします。私のアプリケーションにはたくさんの画面があり、本当に色を変えることを確かめるために各ペインにスタイル()を設定する必要はありません。選択した色に基づいて色が変わるCSSファイルがいくつかありますColorPickerでこれは可能ですか?私はあなたがJavaコードを使ってテキストファイルを書いて、それに ".css"拡張子を付けることができることを認識していますが、これを達成する他の方法はありますか?

FXのこの種の「ベストプラクティス」は何ですか?

+0

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

答えて

3

modenaのすべてのものに基づいている色がいくつかあります。私は私が今見つけることができない、どこかの例があったが、基本的に

  • -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

「カスピアン」をチェックアウトすることもできます。使用されている正確なスタイルシートがデフォルトであることを確認したい場合はcssを使用します。ここにリンクがあります:https://gist.github.com/tmazeika/c90c03c645d18722ddb0 – Chris

+0

デフォルトのスタイルシートは、しばらくの間、CaspianではなくModenaでした。私はコンピュータに戻ったときにリンクを投稿します。 –

+1

私の悪い、あなたの権利。こちらはmodenaです:https://gist.github.com/maxd/63691840fc372f22f470 – Chris