JavaFX Nightに参加してきた #javafx_ja


http://javafx.doorkeeper.jp/events/16670

日時：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さん

http://www.slideshare.net/btnrouge/javafx-dialogs


##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)`とか

## サンプルコード

```java
//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さん

http://www.slideshare.net/YaSuenag/heap-statsfx-analyzer

https://github.com/YaSuenag/HeapStatsFXAnalyzer

## 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
https://github.com/YaSuenag/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さん


http://www.slideshare.net/skrb/bind-me-softly

※メモが甘かったので、一部は@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`はプロパティ値が更新されるかもしれない時に呼ばれる。

```java
prop.addlistener( (observable, oldValue, newVlue)-> {
                  //ChangeListenerで登録する処理
                 });

prop.addlistener(  observable -> {
                  //InvalidationListenerで登録する処理
                 });
```

##自作クラスでPropertyを作成する
setter/getterだけでなく`xxxProperty()`メソッドを作成する必要がある

```java
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

```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>`とか

```java
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