日時:2014-11-25(火)19:00 - 21:00
会場: オラクル青山センター
主催:日本JavaFXユーザグループ
所感
新規に追加予定のダイアログクラス、既存SwingアプリのJavaFXへのマイグレーション、Propertyの構成方法とBindings機能の紹介など。
ダイアログクラスが現状サポートされていないのは驚いた。後述のバインディングと合わせれば、エラーやワーニング処理はだいぶ簡単に実装できるようになると思われる。
JavaFXへのマイグレーションは、Swingとまったく別の完全新規であるJavaFXである以上、既存のSwing向けライブラリを資産として使えないことが多そう。Date&TimeAPIライブラリに用意されている従来クラスとの変換メソッドのように、Swing用のライブラリと相互互換できるようなメソッドがあれば、マイグレーションも進むのかも。(ある?未調査)
チャート(javafx.scene.chart
)を描く際は、ツールチップ(javafx.scene.control.Tooltip
)を利用すると重い、複数チャートの合成ができないため、利用するには少し自作・工夫が必要とのこと。
BindはJavascriptのなどに存在するプロパティ/バインディングのような機能。連携すべきデータの更新を検知し、自動的に値を更新する。Java8の学習として少し実装して利用したことがあるが、ActionListener
などを意識せずに実装できるので、コーディングがラクだった。論理演算なども利用可能。
JavaFXにダイアログがやってくる @btnrougeさん
8u40から追加予定のダイアログ
JavaFXには今までDialog
クラスがなく、開発者それぞれが作成する必要があった。
が、2015年3月リリース予定のJDK1.8 8u40でDialogクラスが数種類追加される。
http://code.makery.ch/blog/javafx-dialogs-official/
ダイアログ名 | 概要 |
---|---|
Alert | ButtonTypeを戻す |
TextInputDialog | 入力されたテキストを戻す |
ChoiceDialog | 選択アイテムを戻す |
Dialog | 全てのダイアログのスーパークラス |
--
Dialogの概要
Dialog
はDialogPane
をレイアウトとして生成される。
DialogPane
には主にTitle
、HeaderText
、ContentText
、ButtonTypes
領域が存在する。#Alert系ならば、Graphic
も
Alert
で生成できるダイアログは主に以下のとおり。
タイプ | 画面構成 |
---|---|
INFORMATION | インフォメーションアイコンとOKボタン |
WARNING | ワーニングアイコンとOKボタン |
ERROR | エラーアイコンとOKボタン |
CONFIRMATION | クエスチョンアイコンとOKボタン、キャンセルボタン |
NONE | デフォルトではアイコンなし、カスタムボタン追加可能 |
全てのダイアログでボタンは追加可能
Dialog
はStage
のかわりに使うことができる。
Stageのような役割だが、Stageではない(厳密には中で生成しているけれど)
ダイアログを出すにはOprional<R>
を返すshowAndWait()
やshow()
で起動する。
戻り値は空の場合もあるので、Optrional<R>
で受ける。
Dialogの種類 | 戻り値R
|
---|---|
Alert |
ButtonType (ButtonType.OK とか) |
TextInputDialog |
String(入力文字列) |
ChoiceDialog |
チョイスボックスにセットした型 |
setHeaderText(null)
でのっぺりしたダイアログができる。
ダイアログの大きさを変更したいときは、DiarlogPane
のサイズを変更しないと変わらない。
alert.getDiarogPane().setPrefSize(400d, 300d)
とか
サンプルコード
//CONFIRMATIONダイアログ生成
Alert alert = new Alert(AlertType.CONFIRMATION);
//DaialogPaneの各領域に値を設定
alert.setTitle("Confirmation Dialog");
alert.setHeaderText("Look, a Confirmation Dialog");
alert.setContentText("Are you ok with this?");
//Alertダイアログなので、戻り値はOprtional<ButtonType>
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK){
// ... user chose OK
} else {
// ... user chose CANCEL or closed the dialog
}
詳細は
JavaFX アドベントカレンダー 8日目で解説予定
http://www.adventar.org/calendars/380
HeapStats loves JavaFX @YaSuenagさん
HeapStatsとは
HeapStats/jp Wiki
http://icedtea.classpath.org/wiki/HeapStats/jp
HeapStatsはJavaVMのヒープやGC状況を監視する軽量なOSSツール。
次の二つで構成される。
エージェント(agent) - JavaVMの情報を収集するJVMTIエージェントプログラムです。
アナライザ(analyzer) - 上記の情報を解析する Javaアプリケーションプログラムです。
今回はHeapStatsのGUI(Swing)をJavaFXにした話。
本家HeapStatsはアナライザのGUIがJavaSE6、Swingベース。あまりよろしくない。
HeapStatsFXAnalyzer
プラガブル(Plagable)にしてある。(プラグインを作成することで機能追加を誰でもできる)
以下の恩恵が欲しくてJavaFX8にマイグレーションすることにした。
- SwingNodeが使える
- FXMLを利用したGUI作成
- JavaFX標準機能のChartを使う
- Taskや国際化機能
アプリの構成はHeapStats1.0相当のアナライザをFXで実装。プラグインで機能拡張が可能
HeapStatsのプラグイン
以下の条件を満たせば、HeapStatsFXAnalyzerのプラグインとして認識される。
- FXMLを含むJAR形式
- HeapStatsのPluginContorollerを継承している
- FXMLを含むパッケージ名を本体のpropertiesに設定する
- libにJARと関連ライブラリを配置しておく
各プラグインはタブが一枚割り与えられる。
プラグイン間のデータの受け渡しは各プラグインのコントローラに直接アクセスしている。
あまりいい案では無いと思っているので、いい案待っている。
FXで困ったところ
- ダイアログがない。自作で解決した。8u40が楽しみ。
- 複数Chartの合成に対応していない。StackPaneと透過を使って複数Chartを無理やり組み合わせいた時期もあったが、複数枚のChartに分割で落ち着く。
- ChartのToolTipが重い。自作して解決。
- Animated=trueなAreaChartで多要素の描画をさせるとシンボルが表示されない。
JavaFXで困っているところ
- SwingNodeが絡むと画面が一部ブラックアウトする - ChartのSeriesを含むFXMLがSceneBuilderでロードできない。
- ウインドウのリサイズがWindowsとLinuxで異なる。
- SwingNodeでドラッグアンドドロップイベントがおかしい。
困っていることは現在進行形の悩みなので、GitHubフォークしてプルリクしてくれると嬉しい
Bind Me Softly @skrbさん
※メモが甘かったので、一部は@skrbさんが書かれた以下記事から記載しています
JavaFX 2で始めるGUI開発 第6回 プロパティとバインド
http://itpro.nikkeibp.co.jp/article/COLUMN/20121219/445461/
PropertyとBind()の紹介、そしてそのユースケースの紹介
Property
JavaFXのProperty
はJava Beansベース。Bind
の基本となる。
Property
インターフェースには各種プリミティブ型、ObjectProperty
, StringProperty
, ListProperty
, SetProperty
などのクラスがある。
https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/Property.html
Propertyへのイベントリスナーの登録
Immediate(ChangeListener
)とLazy(InvalidationListener
)な更新検知ができる。
Lazyな更新検知を主に使うことが多いはず。新しいプロパティ値が検知されたときがChangeListener
、InvalidationListener
はプロパティ値が更新されるかもしれない時に呼ばれる。
prop.addlistener( (observable, oldValue, newVlue)-> {
//ChangeListenerで登録する処理
});
prop.addlistener( observable -> {
//InvalidationListenerで登録する処理
});
自作クラスでPropertyを作成する
setter/getterだけでなくxxxProperty()
メソッドを作成する必要がある
public class Greeting {
private StringProperty text = new SimpleStringProperty("");
public final StringProperty textProperty() { return text; }
public final void setText(String newValue) { text.set(newValue); }
public final String getText() { return text.get(); }
}
Bind
JavaFXのBindはプロパティとプロパティを自動的に同期させることができる。
ただし、通常は一方通行。
双方向のBindもできる。bindBidirectional()
を使う。
例:
IntegerProperty x
にIntegerProperty y
をバインド(x.bind(y)
)すると、y.set(20)
となった時に自動的にx
も20
になる。
Utility ClassとしてBindings
も存在する。
https://docs.oracle.com/javase/8/javafx/api/javafx/beans/binding/Bindings.html
when()
などを利用すると、論理演算も行なったプロパティ制御が可能
例:circle
の半径をscene
の幅、高さの短い方の半分に同期する。
※こちらは以前自分がバインディングした時の例です
https://github.com/budougumi0617/Java8Education/blob/master/src/main/java/ch4/ex04/Ex04.java
circle.radiusProperty().bind(
Bindings.divide(
Bindings.when(
Bindings.lessThanOrEqual(scene.widthProperty(),
scene.heightProperty()))
.then(scene.widthProperty())
.otherwise(scene.heightProperty()), 2));
LowLevel API
バインディングクラスのcomputeValue
メソッドをオーバーロードすることで、バインドを実現します。
例えば3つのスライダーからカラーを生成するBinding<Color>
とか
ObjectBinding<Color> objectBinding = new ObjectBinding<Color>() {
{
super.bind(slider1.valueProperty(),
slider2.valueProperty(),
slider3.valueProperty());
}
@Override
protected Color computeValue() {
return Color.color(slider1.valueProperty().get(),
slider2.valueProperty().get(),
slider3.valueProperty().get());
}
};
UseCase
ユースケース1
知らないうちに使っている。xxxView
を使っていると自動的に使っている。
ユースケース2
Node-Node、Node-Model間でデータ同期をするために使う。
ユースケース3
Rule/Validationとして。
DisableProperty
にバインドしたり。
LawLevelで数値を弾くようにするだとか。LayoutでSceneの大きさに追従させるとか。
ユースケース4
アニメーションとして利用する。
いろふさん絵描き歌 by JavaFX その 2
http://skrb.hatenablog.com/entry/2012/12/22/235800
LT1 サーバーサイドJavaFX @mine_neckさん
サーバサイドでもJavaFXを使ってみた話。
SoundCloudから取得した音源をサーバで流す
https接続をサポートしていないし、SoundCloud側のAPIもメンテが雑で大変だった
LT2 いまさら始めるJavaFX @mshdktomさん
パーサーとかをGUI化するために始めた。
最新のGUI実現方法を知りたかった。
ドラッグアンドドロップが簡単
Java8はストリームでデータ加工されるので大規模処理がはんぱなさそう
だけど、後方互換考えると大変そう。
参考
JavaFX 8 Dialogs
http://code.makery.ch/blog/javafx-8-dialogs/
HeapStatsFXAnalyzer
https://github.com/YaSuenag/HeapStatsFXAnalyzer
Java技術最前線
http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248243/
JavaFX Advent Calendar 2014
http://www.adventar.org/calendars/380