質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Q&A

解決済

1回答

4428閲覧

UIの外観を動的に変更する事について

koban

総合スコア12

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

0グッド

2クリップ

投稿2016/09/07 14:04

Swingで幾つか業務アプリケーションを開発し、現在JavaFxを勉強しています。
JavaFXでは、UIの外観設定を主にCSSを用いる事を学びました。

動的に外観を変更する方法がとても面倒くさいと思っています。

例えば、TextFieldを以下の属性で外観設定するとします。

①数量入力用として用いるなら右寄せ、文字なら左寄せ。
②入力値によってbaseの色を変更する。

.setStyleで実現しようとすると、指定以外の他CSS属性全てが上書き消去されるので、①の属性を設定する時に
②の属性も併せて指定する必要があります。

.getStyleClass().add で実現しようとすると、既にCSS属性がlistにあれば反映されないので、該当するStyleClassを把握し消去してから追加しなければならないと思っています。

外観パターンが増えていく程、面倒くささが飛躍的にUPしていきます。

そもそも動的に変更しようとする事が間違いなのでしょうか?
それとも私の考えが間違っていて、外観の動的に変更に関して、違うやり方があるのでしょうか?

ご教授の程、よろしお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

自分もJavaFXについて初心者なのでフレームワークなどの知識もありませんが、素朴にJavaFXに触れてみた者の意見として聞いてください。何かのヒントにでもなれば幸いです。

まず、swingに比べJavaFXの外観を設定する方法がややこしくなっているというのは若干誤解があると思いました。swingでは困難だった「アプリケーションの実装を一切変えずに外観をきめ細かく指定できる」ことを達成した場合にそれなりの手間をかけるだけの話ではないでしょうか。もしcssによる外観設定を不要としてプログラム上に色などが定義されていてそれに従いハードコードしてよいならswingでもJavaFXでも大差ないと思います。より見てくれるの良いものを作ろうとしているのだから多少のめんどくささは頑張って克服しようかぐらいの気持ちで自分はやってます。

①数量入力用として用いるなら右寄せ、文字なら左寄せ。

数字を入力するためのTextFieldと文字を入力するためのTextFieldの外観を変えたいのは要するにこの2つのTextFieldは違うものだからと言えると思います。違うものは違うクラスにするのが単純な解決法で、違うクラスならcssでクラス毎の外観をそれぞれ個別に指定するのは自然にできます。少なくとも画面上にある一つ一つのコントロールに一々ALIGNMENTを指定する必要はないと思います。
一方ごく小規模なものであれば、右寄せ・左寄せなどをcssファイル上で指定する以外にSceneBuilderのようなGUI設計ツール上で設定できるので(cssで後から変更できなくていいような外観属性なら)それでもいいように思います。

②入力値によってbaseの色を変更する。

これは動的に変化する「状態」なので質問者さんがお考えのpseudoclassとして制御するのが適切だろうと思います。外観パターンが増えていくほど複雑になるというのはおっしゃるとおりですが、①で述べたような方法で動的な状態による外観とそれ以外の静的に決まる外観をきちんと区別することでパターンは最小限にできるのではないでしょうか。
それはそれとして自分も同様にpseudo classをまじめに制御しようとして悩んだことがあります。それはgetStyleClass#addする際に必ず相反する状態をgetStyleClass#removeしないといけない点です。これはいちいちやるのは面倒なので例えばあり得る状態をenumで定義してやって状態を変更するようなメソッドで自動的にremoveしてくれるようにするといった工夫ができるかも知れません。

java

1enum TextState { 2 Normal, 3 AnotherNormal, 4 Error, 5} 6... 7static void setTextState(Control control, TextState newState) { 8 ObservableList<String> styleClass = control.getStyleClass(); 9 // あらかじめ相反する状態を削除する 10 for (TextStete state : TextState.values()) { 11 styleClass.remove(state.toString()); 12 } 13 // あらたな状態を設定する 14 styleClass.add(newState.toString()); 15}

訂正:
時間がたってからのコメントで恐縮ですが内容におかしな点があることに気づきました。疑似クラス(pseudo class)の制御をgetStyleClassでやるとコメントしましたがこれは変ですね。JavaFX 8からの機能に文字通りPsudoClassというのがありこちらを使ってやるべきだと思います。getStyleClassで表現するのは文字通りstyle classであってこちらは動的に変えるようなものではないと思います。PsudoClassを使うと疑似クラスのON/OFFはもっと単純に変更できました。
失礼しました。

投稿2016/09/24 15:24

編集2017/01/24 15:07
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koban

2016/09/26 11:06

ご回答ありがとうございました。ご回答者さんのおっしゃる通り、静的な外観と動的な外観の区分けをしてなかったと気づかされました。Swingではbuilderパターンでコントロールを作る癖がついてたので・・・JavaFXの思想もちゃんと理解して勉強します!動的制御に関してもEnumを用いる考えがなかったで為になりました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問