LoginSignup
8
9

More than 5 years have passed since last update.

JavaFX Nightに参加してきた #javafx_ja

Last updated at Posted at 2014-11-30

日時: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の概要

DialogDialogPaneをレイアウトとして生成される。
DialogPaneには主にTitleHeaderTextContentTextButtonTypes領域が存在する。#Alert系ならば、Graphic

Alertで生成できるダイアログは主に以下のとおり。

タイプ 画面構成
INFORMATION インフォメーションアイコンとOKボタン
WARNING ワーニングアイコンとOKボタン
ERROR エラーアイコンとOKボタン
CONFIRMATION クエスチョンアイコンとOKボタン、キャンセルボタン
NONE デフォルトではアイコンなし、カスタムボタン追加可能

全てのダイアログでボタンは追加可能

DialogStageのかわりに使うことができる。
Stageのような役割だが、Stageではない(厳密には中で生成しているけれど)
ダイアログを出すにはOprional<R>を返すshowAndWait()show()で起動する。
戻り値は空の場合もあるので、Optrional<R>で受ける。

Dialogの種類 戻り値R
Alert ButtonTypeButtonType.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な更新検知を主に使うことが多いはず。新しいプロパティ値が検知されたときがChangeListenerInvalidationListenerはプロパティ値が更新されるかもしれない時に呼ばれる。

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 xIntegerProperty yをバインド(x.bind(y))すると、y.set(20)となった時に自動的にx20になる。

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

8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9