【注意】 この項目は、JavaFX 2.0以降の情報が書かれています。 JavaFX 1.x系以前の情報はこちら。 |
JavaFXとは、Javaの標準GUIライブラリである(Java 8以降)。お金が溶けるFXとは何の関係もない。
JavaFXはサン・マイクロシステムズ社がプログラミング言語として開発した。同社の買収したForm Follows Function (F3)とSavaJeと呼ばれるJava関連技術を発展させて2008年12月にパージョン1.0がリリースとなった。
2009年8月にサン・マイクロシステムズはOracleに買収され、Java及びJavaFXはOracleが引き継ぐところとなったが、2010年9月OracleはJavaFX 2でJavaFX Scriptを廃止することを発表[1]。これによりJavaFXは全く別物のGUIライブラリへと生まれ変わることとなる。
これまでJavaの標準GUIライブラリはSwingであったが、今後はJavaFXを標準GUIライブラリとしていくことも発表された。
JavaFX 2.0は2011年10月10日にリリースされたので、一口にJavaFXといってもこの2011年10月の前と後では全く別物を指している。Web上で情報を探したり、書店で書籍を探したりするときは日付に注意されたい。
JavaFX 2.2の次のバージョンは3.0となる予定だったが、2014年3月18日にリリースされたJava 8以降では標準ライブラリとしてJava仮想マシンに組み込まれることに(Java 7 Update2以降であれば標準搭載されてはいる)なったため、JavaのバージョンにあわせてJavaFX 8になり大きくバージョン番号が飛ぶことになった。
2018年3月にOracleは、Java 8でJava仮想マシンに組み込んだJavaFXを、再びJava仮想マシンから切り離す方針であることを発表した。2018年9月リリースのJava 11(バージョン番号についてはJavaの記事を参照)から実施された。標準とは何だったのか。
JavaFXはOpenJFXとしてオープンソースプロジェクトとなり、Java 11リリース後はGluonという企業が実質的にJavaFXの開発を引き継いでいる。Java本体とは独立した開発なのでバージョン番号もJava本体とは一致するとは限らないはずだが、実際はJavaのバージョンに一致したJavaFXを用いる形で配布されている。
Java 11以降Oracle以外からもJava仮想マシンが配布されるケースが増えてきたが、BellSoftが配布するLibericaJDKにはJavaFXが同梱されているバージョンもある。
Oracleは、JavaFXの分離により「OpenJFXはJava本体の開発ペースに左右されずに開発が進む」というメリットがありそうな表現をしているが、Java7の時代からJavaのリファレンス実装になったOpenJDKでは、もともとJavaFXはJava仮想マシンに統合されておらず、Javaバージョンが7のままでもJavaFXは2.0から2.2までアップデートしていたし、Java8リリース後もJava 8u40の時に機能追加が行われており、これまでもOpenJFXはJava本体の開発ペースに縛られてはいなかった。
むしろ、最新のJava仮想マシンのリリース時に対応するJavaFXが同時リリースされる保証がなくなる上に、ひっそりと開発中止になる可能性すら否定できなくなるという深刻なデメリットがあるのだが、その点についてOracleは一切触れていない。
JavaFXを切り離す一方で、Oracleは旧来のGUIライブラリであるAWTやSwingはJava内に残すとしている。しかし、AWTやSwingについてもJavaFXともどもサポート企業を探すとしており、それらの地位も未来永劫安泰というわけではなさそうである。将来、Javaは標準GUIライブラリを持たなくなるということかもしれない。
MVC(モデル・ビュー・コントローラー)モデルでGUIを作成する。
モデルはユーザー(プログラマー)が各自でクラスを作成する。コントローラーについてもユーザーがクラスを作成するが、書き方についてはJavaFX独自の作法がある。
ビューの部分はJavaのソースコードに記述することも可能だが、FXMLというXMLで分離して記述できることが特徴[2]。このFXMLをGUIを通じて作成するScene Builderというオープンソース・ソフトウェアがあり[3]、これによって視覚的にGUIを設計することが可能になった。
フォントや色などの外観はFXMLにCSSを組み合わせることでも変更することができ、さらにこのCSSを外部ファイルとして独立させることも可能である。
Swingなどで既にGUIをマスターしている人には当然なのかもしれないが、JavaFXのGUIを使用すると、GUIに変更を行うためのスレッド(Application Thread: SwingでいうEvent Dispatch Thread)が自動的に生成される。(動画処理などを除き)すべてのGUI変更命令はこのスレッドに集められ、一本化されてから実行される。
ユーザーが明示的に作ったものでないにもかかわらず、このスレッドの存在を意識してコードを書かないと、マルチスレッドの罠にはまって理解できない動作に悩まされることになる。
JavaFX 2.x系では、Swingの中にJavaFXの部品を入れることはできたが、逆は出来なかった。しかし、JavaFX 8以降では、SwingNodeの導入により相互運用することが可能になっている。
プラットフォームはJava仮想マシンが動作する環境、すなわちWindows、Mac、Linuxだが、実用性や安定性を別にすればiOSやAndroidについても以下のようなプロジェクトが存在する。
2015年5月現在、Java自体がWindows8以降で追加されたModern UI(旧称Metro)に対応していないため、現時点ではデスクトップアプリケーションの開発が主体になると思われるが、JavaFX自体にはタッチやスワイプなどのタッチパネル操作を前提にした項目も存在しているので、将来的にはJavaFXでモバイルアプリを開発できる日が来るのかもしれない。
Linux環境のJava仮想マシンとしては、ハードウェアの違いにより通常のIntel系CPU用以外にARM用のJava仮想マシンが存在するが、2015年1月OracleはARM系プロセッサ向けのJava仮想マシンからJavaFXを省くという決定をした。
Oracle以外の実装であるOpenJDKでは引き続きJavaFXのサポートが続けられているが、コア機能に限定されているようである。浮動小数点演算がハードウェア実行かソフトウェア実行かにより制約を受けるらしい。
OpenJFXはオープンソースなので、それをコンパイルしてOracleのARM用のJava仮想マシンに組み込むという荒業もあるらしいが、かなり複雑な工程を要する。
前述のLibericaJDKにはARM用のJavaFXを同梱したバージョンが存在する。
JavaFXはFlashなどのWebコンテンツ向けGUI開発環境に対抗して投入された経緯があるが、この分野ではHTML5などに大きく後れを取ってしまい、一般的には遅すぎる投入であったと考えられている。
これに対し私見ではあるが、別の観点からするとJavaFXの投入が早すぎたのではないかといえる一面があることについて述べようと思う。
たとえば印刷機能ですら、JavaFX 2.0の時点では不十分で、JavaFX8になってからようやく本格的にサポートされた。2015年2月の時点で、タスクトレイのアイコン(SwingですらなくAWTのクラスを使用しなければならない)やダイアログボックス(2015年3月のJavaFX 8 update 40で遅ればせながら導入)など、かゆいところに手が届かない未熟な一面が見てとれる。
すでにかなり遅れをとっていたので投入を急がざるを得なかったのはわかるが、時間が解決してくれる可能性もあるので今後に期待ということになるのであろうか。
もう一点、より深刻なのが、Java8から導入されたnull対策であるOptionalクラスが活用されていない点である。
JavaFXでは、リストボックスの未選択状態などを表現するのにnullを多用している。もし導入がJava6でなくJava8からであったなら、Optionalクラスのとてもよい活用例になっただろうと思われる。
しかし、JavaFX 2.0はJava6上でも利用できるように設計されているので、当然Optionalは使用されていない。その結果、互換性の関係からJavaFX 8になってもやはり使用されていない。もし今から導入しようとすると、各部品に設定されている選択状態などの値を格納する変数のクラスを変更しないといけなくなるので、互換性のことを考えると現段階から導入するのは絶望的なのではないだろうか。
IntegerProperty(あるいはObjectProperty<Integer>にnullを格納)の代わりにObjectProperty<OptionalInt>やObjectProperty<Optional<Integer>> 、ObjectProperty<T>の代わりにObjectProperty<Optional<T>>とすると利用できないこともないが、bindする部分を自力で用意せねばならず、かなり不格好である。ちなみにObjectProperty<Optional<Integer>>とObjectProperty<OptionalInt>ではそれほどbindするときの手間が変わらないように見えるが、Optional<Integer>では使えるのにOptionalIntでは使えないメソッドがあったりするので、後者の方がまだシンプルそうに見えるが、前者のほうがいくらか扱いやすい可能性はある。
掲示板
急上昇ワード改
最終更新:2024/12/27(金) 13:00
最終更新:2024/12/27(金) 13:00
ウォッチリストに追加しました!
すでにウォッチリストに
入っています。
追加に失敗しました。
ほめた!
ほめるを取消しました。
ほめるに失敗しました。
ほめるの取消しに失敗しました。