JavaFX

JavaFX の SplitPane を試してみた。

JavaFX

JavaFX の SplitPane の存在は知っていたが使う機会が無かったので使い方を知らないまま今日に至っています。

とりあえず簡単な使い方だけでも知っておこうとググってみたのですが日本語での情報を見つけることができませんでした。(>_<。)

しかたないので API ドキュメントをサラッと 読んで 眺めてみることにしました。

Class SplitPane

http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/SplitPane.html#getDividerPositions–

縦、横の指定や分割位置などが設定できるようでメソッド数も少なくシンプルなものです。

ただ、私の英語力及び Java 力では理解できないものがあり目から汗が出ています。

Example に sp.setDividerPositions(0.3f, 0.6f, 0.9f); とあるんだけど

最後の引数の 0.9f は無くてもいいんじゃないの?

最後のスペースは自動計算されるはずでは?

なぜなんだろう?

何か意味があるはずなんだろうけど・・・

と言うことでサクッとプログラムを組んで動作確認してみました。

上記のように ? の状態なのでこれであっているか自信はありません。

ラベルをみっつ均等に表示させ、左のラベルは全体の33パーセントより小さくさせない、右のラベルは全体の33パーセントより大きくさせないという制限も付加してみました。

このプログラムの実行結果は下図のようになります。

初期状態

1

左の Divider を右へドラッグして左のラベルを大ききします。

2

左の Divider を左へドラッグして左のラベルを小さくしようとしますが制限がかかっていて小さくなりません。

3

右の Divider を右へドラッグして中央のラベルを大きくします。

4

右の Divider 左へドラッグして右のラベルを大きくしようとしますが制限がかかっておおきくなりません。

5

これって以外と便利に使えるかもしれないですね。

なんで日本語の情報がないんだろう?

シンプルすぎてスルーされているんだろうか?

最後に、ラベルのテキストは私個人の好みであり所属する会社の公式な好みではありません。(ヲヒ

Hatena タグ:

このエントリーをはてなブックマークに追加
Share on Facebook

TextField を 0 から 9 までの数値しか入力できないようにしてみた

JavaFX

このプログラムは TextField に入力制限をかけたいなぁって思ってどうすればいいんだろう?ってネットサーフィンしていたときに見つけたものです。

Java 8u40 では Formatted Text が追加されるらしいのですが、お試し版を使ったサンプルコードの紹介がまだ見当たらない現状なのでφ(..)メモメモ

ちなみに Alert Dialogs はみんな待っているのでサンプルコードはもう出ていますね。

あと、Spinner も追加されるようです。

JavaFX はまだまだ足りないものがあるとあちこちで言われていますが着実に進化しているようです。

それでは忘備録として下記コードを書き留めておきます。

このプログラムは TextField の lengthProperty にリスナーを登録して入力した値を判定して処理してます。

これだと何かしらのイベント発生時に TextField の入力値を取得して正規表現で判定して問題あればアラートダイアログ出して入力し直してもらうという方法より場合によってはいいかもしれません。

小ネタですがもう暫くは活躍してもらえそうです。(^_^)

Hatena タグ:
このエントリーをはてなブックマークに追加
Share on Facebook

JavaFX の MeshView を試してみる その2

JavaFX

このエントリーは JavaFX の MeshView を試してみる の続きです。

今回は立方体を表示させるプログラムを組んでみます。

立方体だからといって複雑になり難しくなることはありません。

しょせん、最小構成のポリゴン(  TriangleMesh ) の集まりです。

立方体の頂点の座標は下図のようにしました。

box

 

この立方体に貼るテクスチャは次のものを使います。

duke_uv

 

これを先ほの立方体へ貼ります。

解りやすくするためにテクスチャの座標とインデックスをいれた画像を用意しました。

t_map

 

前回のエントリーをお読みになった方は下記のソースコードを見たら何をやっているか理解できるでしょう。

今回はちょっとピッキング API でお遊びをいれています。

ピッキング API で取得した情報を標準出力に表示させたり、

オブジェクトの拡大縮小をやっています。( この部分は JavaFX の標準機能だけでシンプルな 3D トイピアノをつくろう を参考にしてください。)

scene.setOnMouseClicked(event -> {
    PickResult pickResult = event.getPickResult();        
    System.out.println(“PickResult Node : ” + pickResult.getIntersectedNode());
    System.out.println(“PickResult Face : ” + pickResult.getIntersectedFace());
    System.out.println(“PickResult TexCoord : ” + pickResult.getIntersectedTexCoord());
    System.out.println(“PickResult Distance : ” + pickResult.getIntersectedDistance());          
    if (pickResult.getIntersectedNode() == meshBox) {
        Point3D point3d = pickResult.getIntersectedPoint();
        if (point3d.getX() != 0.0d && point3d.getY() != 0.0d && point3d.getZ() != 0.0d) {
            meshBox.setScaleX(abs(point3d.getX() / 100.0d) * 1.8d);
            meshBox.setScaleY(abs(point3d.getY() / 100.0d) * 1.8d);
            meshBox.setScaleZ(abs(point3d.getZ() / 100.0d) * 1.8d);
        } else {
            meshBox.setScaleX(0.5d);
            meshBox.setScaleY(0.5d);
            meshBox.setScaleZ(0.5d);
        }
    } else {
        meshBox.setScaleX(1.0d);
        meshBox.setScaleY(1.0d);
        meshBox.setScaleZ(1.0d);
    }
});

これによって得られる情報は下記のようになります。

PickResult Node : MeshView@7bc4dd1a
PickResult Face : 10
PickResult TexCoord : Point2D [x = 0.4647918545001403, y = 0.5826962887300013]
PickResult Distance : 675.187084447299

最後の PickResult Distance はカメラからの距離となります。

ついでに 3D オブジェクトの情報もとってみました。

System.out.println(“PointElementSize : ” + this.getPointElementSize());
System.out.println(“TexCoordElementSize : ” + this.getTexCoordElementSize());
System.out.println(“FaceElementSize : ” + this.getFaceElementSize());

プログラムの実行結果で得られた値は下記のようになります。

PointElementSize : 3
TexCoordElementSize : 2
FaceElementSize : 6

これらは上から 3, 2, 6 といつも同じ数値を返すようです。

私はてっきり各配列の要素数を返すものだと思い込んでいたので少しばかり悩んで時間を無駄にしてしまいました。

これらの存在意義が解らないので未だにすっきりしていないし、間違って解釈している可能性もあるので霧の中にいるような感覚が今もあります。

あと、今回は複数のフェイスで 3D オブジェクトが構築されているので次のメソッドを使用します。

javafx.scene.shape.TriangleMesh クラスの ObservableIntegerArray getFaceSmoothingGroups() メソッドです。

これを使いフェイスをグルーピングしてスムーズに表示させることが可能となるようです。

this.getFaceSmoothingGroups().addAll(
        0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5
);

上記コードは、triangle A-C-B と triangle C-D-B をグルーピング ( 0 )

triangle E-F-G と G-F-H ( 1 )、triangle A-B-E と triangle E-B-F ( 2 ) … という具合にグルーピングしていきます。

最終的にはフェイスの数と faceSmoothingGroups の配列の要素数は等しくなります。

これを間違えてもコンパイルエラーにはなりませんし、プログラムもエラーで止まることなく実行されてしまいます。

ただ肝心の 3D オブジェクトは表示されることは無いでしょう。

あっ、空だと表示されますね。(当たり前か)

さて、この機能なんですが本当に効果があるのでしょうか?

私の環境では違いを確認できませんでした。

このような小さなプログラムでは効果が確認できないのかもしれません。

最後にこのプログラムの動画を貼っておきますので興味のある方はご覧くださいませ。

 

JavaFX 楽しすぎるから年末の TODO が減らない! どうしよう(>_<。)

Hatena タグ:
このエントリーをはてなブックマークに追加
Share on Facebook

F(X)yz を SceneBuilder 2.0 で使ってみた。

JavaFX

JavaFX の 3D ライブラリとして現在活発に開発が進められている F(X)yz が SceneBuilder 2.0 で使用できることを José Pereda さんから教えてもらったので早速少しだけ試してみました。

まず、https://github.com/Birdasaur/FXyz からライブラリをダウンロードします。

それから SceneBuilder 2.0 にダウンロードしたライブラリをインポートします。

Library の右側に小さくある歯車のボタンをクリックして出てくるプルダウンメニューより Import JAR/FXML File… を選択します。

1

 

すると Import Dialog ウィンドウが表示されます。

必要なものだけ選んで Import Components ボタンをクリックします。

2

 

12月23日 午後7時05分追記

Git からダウンロードしたものだと上手のように最新の 3D ライブラリは含まれていません。

必ずプロジェクトをビルドしてからライブラリを追加しましょう。

fx

 

無事にインポートされたら Custom の項目に追加されたのが確認できます。

3

 

ちゃんとビルドしたライブラリをインポートすれば多くの 3D ライブラリが追加されます。

fx2

 

実際に Mesh オブジェクトを表示させるだけのプログラムを組むために下図のように配置及び変形させてみた。

4

 

適当に色を付けて表示させただけのプログラムの実行結果は下図のようになります。

5

SceneBuilder を使っての 3D アプリケーションの正しい開発方法を未だに情報収集できてないので細かいことは良く解らないのでただ使えるじゃんで終わりです。

ちなみにテクスチャを狙い通りに貼る方法は解りませんでした。

最初に述べたように開発が積極的に行われているようなので今後いろんな 3D オブジェクトが追加されるだろうと期待しています。

最近ではクロスの 3D アニメーションなんかは凄いインパクトがありました。

12月23日 午後9時 追記

クロスとカーブスプリング、スプリングも表示させるだけのプログラムを組んで確認しました。

クロスにはテクスチャを貼ることができました。

fx_a

 

fx_b

 

きっと大きな幸せを呼んでくれるライブラリになると期待してます。(^_^)

Hatena タグ:
このエントリーをはてなブックマークに追加
Share on Facebook

JavaFX の MeshView を試してみる

JavaFX

JavaFX 3D API の MeshView は使うことは無いだろうと思いノータッチでいました。

いつか暇な時にでも軽くどんなものなのか見ておこうとずっとほったらかしにして現在に至ってます。

その理由は実際に自分でポリゴンやテクスチャを定義するなんて大変なことはしない。

モデルインポーターを使うのが常套手段だろうと考えてました。

今でもその考えは変わっていませんが少しだけでもどんなものなのか試してみます。

それでは最小構成で頂点をみっつ持つ正三角形を表示させてみることにしました。

いつものようにネット上で情報を拾い集めてあーでもないこーでもないと API ドキュメントを眺めながらやっています。

英語が駄目なので API ドキュメントを眺めていると表現しました。読めません。(>_<。)

よって、いつものように間違いがあるかもしれませんのでご了承くださいませ。

 

このプログラムの実行結果は次の動画のようになります。

 

MeshView オブジェクトを生成するところ以外の部分は下記エントリーを参考にしてください。

JavaFX の標準機能だけでシンプルな 3D トイピアノをつくろう

javafx.scene.shape.MeshView クラスは 3D オブジェクトを生成をするクラスです。

javafx.scene.shape.TriangleMesh クラスのインスタンスを MeshView のコンストラクタに与えて生成します。

TriangleMesh クラスでは頂点、テクスチャ、フェイスなどが定義されます。

先ほどのプログラムのコードで MeshView クラスのインスタンス生成時のコンストラクタの引数の TriangleMesh の拡張クラスをみてみましょう。

ObservableFloatArray getPoints() メソッドで頂点情報を取得して

void addAll(float… elements) メソッドで頂点の位置情報を追加しています。

ObservableFloatArray getTexCoords() メソッドでテクスチャ情報を取得して

void addAll(float… elements) メソッドでテクスチャ位置情報を追加してます。

ちなみにテクスチャの左上は [ 0, 0 ] で右下は [ 1, 1 ] となります。

ちなみにこのプログラムではテクスチャは下図のように使っています。

duke2

ObservableFaceArray getFaces() メソッドでフェイス情報を取得して

void addAll(float… elements) メソッドで頂点に対してテクスチャをマッピングしたフェイスを追加します。

これらは全て配列として扱われています。

このような小さな 3D オブジェクトなら何とかなるでしょうけど複雑なものはお手上げですね。

やっていることは非常にシンプルです。

さて、このシンプルなプログラムの実行結果の動画を見て裏側が何も表示されないのは何故?と思われた方もいらっしゃるでしょう。

その秘密はエコです!

つまり、見えない所はわざわざ高い電気代使って計算しなくてもいいだろうと言う節約です。(^_^;)

本当の所はコンピュータリソースの節約でパフォーマンスアップを狙ったりするんでしょう。

デフォルトのカリングを確認してみます。

次のコードを追加して実行してみます。

    System.out.println(“CullFace : ” + myMesh.getCullFace());

実行結果は次のようになります。

CullFace : BACK

つまり裏側は描写しない設定です。

それではカリングの設定を無しにしてどうなるか確認してみましょう。

次のコードを追加して実行してみます。

    myMesh.setCullFace(CullFace.NONE);

プログラムの実行結果は次の動画のようになります。

 

裏側に表側のテクスチャ画像が暗いグレー色の中に透き通って見えるよう描写されています。

それではカリングの設定をフロントにして確認してみましょう。

次のコードのようにカリングの設定を変更してみます。

    myMesh.setCullFace(CullFace.FRONT);

プログラムの実行結果は次の動画のようになります。

 

フロント側は描写されていません。

裏側は先ほどのカリングの設定が無い場合の表示となっています。

ポリゴンの裏側の描写をしない(デフォルト設定)くらいしか使い道を思いつきませんがいろいろできそうですね。

さて、カリングの設定の確認を先にしてしまって話しが前後していまいましたが

ポリゴンに思い通りにテクスチャを貼るにはどうしたらいいのか確認します。

カリングの設定をデフォルトに戻して本題にうつります。

このプログラムは最小構成のポリゴン( TriangleMesh )なので頂点はみっつです。

正三角形の上の頂点は原点(0f, 0f, 0f)に位置してます。

左下の頂点は -100f, (float) (100 * Math.sqrt(3.0d)), 0f の位置

そして右下の頂点は 100f, (float) (100 * Math.sqrt(3.0d)), 0f の位置です。

    0, 0, 0,         // Top             idx 0
    -w / 2, h, 0,  // Bottom Left   idx 1
    w / 2, h, 0    // Bottom Right idx 2

これらは配列として格納されているので上からインデックスは、0, 1, 2 となります。

次にテクスチャを確認します。
テクスチャは左上が [ 0, 0 ] 、右下が [ 1, 1 ] となるから次のように設定しました。

    1 / 2f, 0,                          // idx 0
    0, (float) Math.sqrt(3) / 2,  // idx 1
    1, (float) Math.sqrt(3) / 2   // idx 2

これも配列として格納されるので上からインデックスは、0, 1, 2 となります。

これらを利用してポリゴンにテクスチャを貼っていきます。

    this.getFaces().addAll(
        0, 0, 1, 1, 2, 2
    );

p0, t0, p1, t1, p3, t3 と頂点座標に対してテクスチャ座標をマッピングしていくだけです。

このテクスチャマッピングを利用して少し遊んでみます。

テクスチャ画像を裏返しで貼ることはできるでしょうか?

試してみました。

次のようにテクスチャマッピングを変更してみました。

    this.getFaces().addAll(
        0, 0, 1, 2, 2, 1
    );

プログラムの実行結果は次の動画のように裏返しで表示されました。(^_^)

 

次は裏側にテクスチャを貼ってみます。

次のようにテクスチャマッピングを変更してみます。

    this.getFaces().addAll(
        0, 0, 2, 1, 1, 2
    );

プログラムの実行結果は次の動画のようになります。

 

裏側に貼られています。

ん? 表側が表示されてなかった。

あれれ?カリングによって裏側は表示されないはずですよね。

つまり、頂点のインデックスを反時計回りから時計回りとしたことで表と裏が逆になっただけということ。

もう少しあそんでみます。

裏側に裏返しのテクスチャを貼ってみます。

簡単ですね。次のようにテクスチャマッピングを変更します。

   this.getFaces().addAll(
        0, 0, 2, 2, 1, 1
    );

プログラムの実行結果は次の動画のようになります。

 

これも先ほどと同じく頂点インデックスが時計回りとなったことを利用しただけです。

さて、ここで表と裏に同じテクスチャを貼るにはどうすればいいでしょうか?

残念ながら JavaFX 3D API には boolean backFaceNormalFlip() メソッドは無いようです。

でも、安心してください。答えは既に出ています。

次のようにテクスチャマッピングを変更してみます。

    this.getFaces().addAll(
        0, 0, 1, 2, 2, 1,
        0, 0, 2, 1, 1, 2
    );

プログラムの実行結果は次のようになります。

 

表と裏にちゃんとテクスチャ画像が表示されました。(^_^)

この方法が良いか悪いかは解りません。

ひょっとしたらもっとスマートは方法があるかもしれません。

最後に裏側の画像を表裏ひっくり返したものにしたい場合は次のようにテクスチャマッピングを変更してみます。

    this.getFaces().addAll(
        0, 0, 1, 2, 2, 1,
        0, 0, 2, 2, 1, 1
    );

プログラムの実行結果は次の動画のようになります。

 

最小構成での確認はこれでおしまいです。

時間があれば立方体でも試してみたいと思います。

JavaFX 楽しくて時間がどんどん溶けていく(>_<。)

Hatena タグ:
このエントリーをはてなブックマークに追加
Share on Facebook

« 古い記事