モジュール javafx.graphics

パッケージjavafx.scene.layout

ユーザー・インタフェース・レイアウトをサポートするクラスを提供します。 各レイアウト・ペイン・クラスはその子に対してそれぞれ異なるレイアウト手法をサポートしており、アプリケーションでは、これらのレイアウト・ペインをネストして、ユーザー・インタフェースに必要なレイアウト構造を実現できます。 レイアウト・ペインのいずれかにノードが追加されると、そのノードのレイアウトはそのペインによって自動的に管理されるようになるため、アプリケーションでノードを直接配置したり、サイズ変更しないようにしてください。詳細は、「ノードのサイズ変更可能性」を参照してください。

シーングラフ・レイアウト・メカニズム

アプリケーションでSceneが作成および表示されると、シーングラフ・レイアウト・メカニズムが自動的に駆動されます。 シーングラフは、レイアウトに影響を及ぼす動的なノード変更(サイズやコンテンツの変更など)を検出し、requestLayout()を呼び出してそのブランチをレイアウトが必要であるとしてマークします。これにより、次のパルスでそのブランチのルートでlayout()が起動され、そのブランチに対して上から下へのレイアウト・パスが実行されるようになります。 このレイアウト・パス中に、各親でlayoutChildren()コールバック・メソッドが呼び出され、その子がレイアウトされます。 このメカニズムは、小さい変更が発生するたびに再レイアウトを実行するのではなく、複数のレイアウト・リクエストを単一のパスにまとめて処理するようにすることで、レイアウト効率を最大化するように設計されています。 したがって、アプリケーションでノードに対してレイアウトを直接起動しないようにしてください。

ノードのサイズ変更可能性

シーングラフは、サイズ変更可能なノード・クラスとサイズ変更不可能なノード・クラスの両方をサポートしています。 Nodeに対してisResizable()メソッドを実行すると、特定ノードをサイズ変更できるかどうかが返されます。 サイズ変更可能なノード・クラスは、許容範囲のサイズ(最小値<=優先値<=最大値)をサポートするもので、親独自のレイアウト・ポリシーと兄弟ノードのレイアウトが必要な場合、その親がレイアウト中にその範囲内でサイズを変更できるようにします。 ノードは、レイアウト・コードでノードのサイズ変更可能範囲を決定するために、次のメソッドをサポートしています。


    public Orientation getContentBias()
    public double minWidth(double height)
    public double minHeight(double width)
    public double prefWidth(double height)
    public double prefHeight(double width)
    public double maxWidth(double height)
    public double maxHeight(double width)

一方、サイズ変更不可能なノード・クラスには、一貫したサイズ変更APIはありません。このため、親によってレイアウト中にサイズ変更されることはありません。 サイズ変更不可能なノードのサイズは、各インスタンスの該当するプロパティを設定することによって、アプリケーションで決定する必要があります。 これらのクラスは最小値、優先値および最大値として現在のレイアウト境界を返し、resize()メソッドは操作なしになります。


サイズ変更可能なクラス: RegionControlWebView
サイズ変更不可能なクラス: GroupShapeText

たとえば、Buttonコントロール(サイズ変更可能)では、その最小サイズ、優先サイズおよび最大サイズを計算し、その親はレイアウト中にそれらのサイズを使用してコントロールをサイズ変更します。このため、アプリケーションでは、コンテンツとプロパティを構成することのみが必要です。

    Button button = new Button("Apply");
一方、Circle (サイズ変更不可能)は親によってサイズ変更できないため、アプリケーションで適切な幾何学的プロパティを設定してサイズを決定する必要があります。
    Circle circle = new Circle();
    circle.setRadius(50);

サイズ変更可能な範囲

サイズ変更可能な各ノードは、それ自体のコンテンツおよびプロパティ設定に基づいて適切な最小サイズ、優先サイズおよび最大サイズを計算します(それぞれ固有のサイズ範囲)。 サイズ変更可能なクラスの中には、最大サイズに制限がないもの(すべてのレイアウト・ペイン)や、最大サイズがデフォルトで優先サイズに固定されるもの(ボタン)があります(各クラスのデフォルト範囲については、個々のクラスのドキュメントを参照)。 これらのデフォルト値は一般的な使用方法に適合することを目指していますが、多くの場合、特定のレイアウトを実現するために、アプリケーションで明示的にノードのサイズ変更可能範囲を変更または設定する必要があります。 サイズ変更可能なクラスには、この目的で最小サイズ、優先サイズおよび最大サイズをオーバーライドするためのプロパティが用意されています。

たとえば、ListViewの優先サイズをオーバーライドするには、次のようにします。

    listview.setPrefSize(200,300);

また、ボタンの最大幅を変更して、スペース全体に表示されるように幅を広げるには、次のようにします。

    button.setMaxWidth(Double.MAX_VALUE);

逆のケースとして、アプリケーションでノードの最小サイズまたは最大サイズを優先サイズに固定する必要がある場合は、次のようにします。

    listview.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
最後に、アプリケーションで固有の計算値に戻す必要がある場合は、次のようにします。
    listview.setPrefSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);

CSSスタイルとノードのサイズ設定

サイズ変更可能なノードのサイズはCSSに依存している可能性があるため、シーンに追加されるまでは、そのノードの境界をアプリケーションから正確に問い合せることはできません。 これは、ノードの多くの側面のスタイル指定(フォント、余白、ボーダーなど)にCSSが使用され、それらのスタイルが優先サイズに影響を及ぼすためです。そのため、CSSが適用されて、親から有効なサイズ範囲メトリックにアクセスできるようになるまでは、ノードをレイアウト(サイズ変更)できません。 このことは、コントロール(およびそれらを含むすべてのペイン)に対して常に該当します。これは、ユーザー・レベルのスタイルシートが設定されていない場合でも、CSSに基づいてデフォルト・スタイルが決定されるためです。 スタイルシートはシーン・レベルで設定されます。つまり、ノードを囲むシーンが初期化されるまで、スタイルを決定することもできません。 シーンが初期化されると、(必要に応じて)パルスごとにCSSがノードに適用され、その直後にレイアウト・パスが実行されます。

視覚境界とレイアウト境界

グラフィカルにリッチなユーザー・インタフェースでは、多くの場合、ノードの視覚境界とレイアウトに使用される境界を区別する必要があります。 たとえば、テキスト・ノードの文字グリフのような近接した視覚境界は、テキストが位置合せされず、先頭と末尾の空白文字が無視されるため、レイアウトに対しては機能しません。 また、アプリケーションによっては、周囲のレイアウトへの影響なく、ノードに効果や変形(バウンシング、ジグリング、ドロップ・シャドウ、発光など)を適用することが必要となります。 シーングラフでのこの区別をサポートするために、Nodeには、レイアウト用にノードの論理境界を定義するlayoutBoundsプロパティ以外に、すべての効果、クリッピングおよび変形が適用された後に視覚境界を定義するboundsInParentが用意されています。

多くの場合、これらの2つの境界プロパティはノードによって異なり、layoutBoundsの計算方法もノード・クラスによって異なります。

境界計算表
ノード・タイプ レイアウト境界
ShapeImageView 幾何学的境界(ジオメトリとストローク)を含みます。 効果、クリップまたは変形を含みません。
Text フォントの高さおよびコンテンツの幅(空白文字を含む)に基づく論理境界です。boundsTypeを設定することによって、文字グリフの周囲に近接した境界を作成するように構成できます。 効果、クリップまたは変形を含みません。
RegionControlWebView 視覚境界に関係なく、常に[0,0 width x height]になります。レイアウト境界よりも大きくなる場合も小さくなる場合もあります。
Group 可視のすべての子の視覚境界(boundsInParent)で構成される集合です。グループに直接設定された効果、クリップおよび変形は含められませんが、個別の子に設定された効果、クリップまたは変形は含められます。これらは子のboundsInParentに含まれているためです。

したがって、たとえば、DropShadowを図形に追加した場合、そのシャドウはデフォルトではレイアウトに組み込まれません。 また、ScaleTransitionを使用してボタンのサイズをパルスした場合、そのパルス・アニメーションがボタンの周囲のレイアウトに影響を及ぼすことはありません。 効果、クリップまたは変形をノードのレイアウトに組み込む必要があるアプリケーションでは、そのノードをグループにラップする必要があります。