1 組込みのレイアウト・ペインの使用
このトピックでは、JavaFX SDKで使用可能な、ペインと呼ばれるレイアウト・コンテナ・クラスについて説明します。レイアウト・ペインを使用すると、JavaFXアプリケーションのユーザー・インタフェースを容易に管理できます。
JavaFXアプリケーションでは、各UI要素の位置プロパティとサイズ・プロパティを設定することにより、手動でUIを配置できます。ただし、より簡単な方法は、レイアウト・ペインを使用することです。JavaFX SDKでは、行、列、スタック、タイルなどの従来のレイアウトの設定および管理を容易にする、いくつかのレイアウト・ペインが提供されます。ウィンドウがサイズ変更されると、レイアウト・ペインにより、そのウィンドウに含まれているノードが、そのノードのプロパティに従って自動的に再配置およびサイズ変更されます。
このトピックでは、JavaFXレイアウト・パッケージで提供される各レイアウト・ペインの概要と単純な例を示します。LayoutSample.java
ファイルには、このトピックで構築するUIのソース・コードが含まれています。LayoutSample.zip
ファイルには、サンプル・アプリケーションのNetBeans IDEプロジェクトが含まれています。
BorderPane
BorderPane
レイアウト・ペインでは、ノードを配置する5つのリージョン(上部、下部、左側、中央、右側)が提供されます。図1-1に、枠線付きペインを使用して作成できるレイアウトの例を示します。リージョンは任意のサイズに設定できます。アプリケーションでいずれかのリージョンが不要な場合は、そのリージョンを定義する必要はなく、そのリージョンにはリージョンが割り当てられません。
枠線付きペインは、上部にツールバー、下部にステータス・バー、左側にナビゲーション・パネル、右側に追加情報、さらに中央に作業領域がある従来の外観に有用です。
ウィンドウが各リージョンのコンテンツに必要なリージョンよりも大きい場合、デフォルトでは、中央のリージョンに追加のリージョンが割り当てられます。ウィンドウが各リージョンのコンテンツに必要なリージョンよりも小さい場合は、リージョンが重なる可能性があります。重なる部分は、リージョンが設定された順序によって決まります。たとえば、リージョンが左側、下部、右側の順に設定され、ウィンドウが小さくなった場合、下部のリージョンが左側のリージョンの上に重なり、右側のリージョンが下部のリージョンの上に重なります。左側、右側、下部の順に設定され、ウィンドウが小さくなった場合は、下部のリージョンが左側と右側の両方のリージョンの上に重なります。
例1-1は、レイアウト・サンプル・アプリケーションによって構築されるUIで使用される枠線付きペインを作成するコードを示しています。各リージョンで使用されるレイアウト・ペインの作成方法については、このトピックの後続の項で説明します。
例1-1 枠線付きペインの作成
BorderPane border = new BorderPane(); HBox hbox = addHBox() border.setTop(hbox); border.setLeft(addVBox()); addStackPane(hbox); // Add stack to HBox in top region border.setCenter(addGridPane()); border.setRight(addFlowPane());
このサンプルでは、枠線付きペインの下部のリージョンは使用されていません。下部のリージョンに何かを追加する場合は、次の文を使用して、nodeを任意のコントロールに置き換えます。
border.setBottom(node);
HBox
HBox
レイアウトは、単一の行に一連のノードを容易に配置できる方法を提供します。図1-2に、HBox
ペインの例を示します。
パディング・プロパティを設定して、ノードとHBox
ペインの端の間の距離を管理できます。スペースを設定して、ノード間の距離を管理できます。スタイルを設定して、背景色を変更できます。
例1-2では、2つのボタンを含むツールバーのHBox
ペインを作成します。
例1-2 HBoxペインの作成
public HBox addHBox() { HBox hbox = new HBox(); hbox.setPadding(new Insets(15, 12, 15, 12)); hbox.setSpacing(10); hbox.setStyle("-fx-background-color: #336699;"); Button buttonCurrent = new Button("Current"); buttonCurrent.setPrefSize(100, 20); Button buttonProjected = new Button("Projected"); buttonProjected.setPrefSize(100, 20); hbox.getChildren().addAll(buttonCurrent, buttonProjected); return hbox; }
例1-1のsetTop()
メソッドは、HBox
ペインを枠線付きペインの上部のリージョンに追加します。この結果を図1-3に示します。
VBox
VBox
レイアウト・ペインはHBox
レイアウト・ペインに似ていますが、ノードが単一の列に配置される点が異なります。図1-4に、VBox
ペインの例を示します。
パディング・プロパティを設定して、ノードとVBox
ペインの端の間の距離を管理できます。スペースを設定して、ノード間の距離を管理できます。マージンを設定して、個別コントロールの周囲に追加のスペースを設定できます。
例1-3では、オプション・リストのVBox
ペインを作成します。
例1-3 VBoxペインの作成
public VBox addVBox(); { VBox vbox = new VBox(); vbox.setPadding(new Insets(10)); vbox.setSpacing(8); Text title = new Text("Data"); title.setFont(Font.font("Arial", FontWeight.BOLD, 14)); vbox.getChildren().add(title); Hyperlink options[] = new Hyperlink[] { new Hyperlink("Sales"), new Hyperlink("Marketing"), new Hyperlink("Distribution"), new Hyperlink("Costs")}; for (int i=0; i<4; i++) { VBox.setMargin(options[i], new Insets(0, 0, 0, 8)); vbox.getChildren().add(options[i]); } return vbox; }
例1-1のsetLeft()
メソッドは、VBox
ペインを枠線付きペインの左側のリージョンに追加します。この結果を図1-5に示します。
StackPane
StackPane
レイアウト・ペインは、前のノードの上に新しいノードを追加して、すべてのノードを単一スタック内に配置します。このレイアウト・モデルは、図形やイメージの上にテキストを重ねる、または一般的な図形を重ねて複雑な図形を作成する操作を容易にする方法を提供します。図1-6は、グラデーションが作成された背景色の四角形の上に疑問符を重ねて作成されたヘルプ・アイコンを示しています。
位置合せプロパティを設定して、スタック・ペイン内での子の配置方法を管理できます。このプロパティはすべての子に影響を与えるため、マージンを設定して、スタック内での個々の子の位置を調整できます。
例1-4では、ヘルプ・アイコンのスタック・ペインを作成します。
例1-4 スタック・ペインの作成
public void addStackPane(HBox hb) { StackPane stack = new StackPane(); Rectangle helpIcon = new Rectangle(30.0, 25.0); helpIcon.setFill(new LinearGradient(0,0,0,1, true, CycleMethod.NO_CYCLE, new Stop[]{ new Stop(0,Color.web("#4977A3")), new Stop(0.5, Color.web("#B0C6DA")), new Stop(1,Color.web("#9CB6CF")),})); helpIcon.setStroke(Color.web("#D0E6FA")); helpIcon.setArcHeight(3.5); helpIcon.setArcWidth(3.5); Text helpText = new Text("?"); helpText.setFont(Font.font("Verdana", FontWeight.BOLD, 18)); helpText.setFill(Color.WHITE); helpText.setStroke(Color.web("#7080A0")); stack.getChildren().addAll(helpIcon, helpText); stack.setAlignment(Pos.CENTER_RIGHT); // Right-justify nodes in stack StackPane.setMargin(helpText, new Insets(0, 10, 0, 0)); // Center "?" hb.getChildren().add(stack); // Add stack pane to HBox object HBox.setHgrow(stack, Priority.ALWAYS); // Give stack any extra space }
例1-4の最後のコード行は、例1-2で作成したHBox
ペインにスタック・ペインを追加して、常にこのペインの右端になるように配置します。この結果を図1-7に示します。
GridPane
GridPane
レイアウト・ペインでは、行および列のフレキシブルなグリッドを作成して、そこにノードを配置できます。ノードは、グリッド内の任意のセルに配置でき、必要に応じて複数のセルをまたいで配置することもできます。グリッド・ペインは、フォーム、または行と列で編成されるあらゆるレイアウトを作成する際に役立ちます。図1-8に、アイコン、タイトル、サブタイトル、テキストおよび円グラフを含むグリッド・ペインを示します。この図では、グリッド行を表示するためにgridLinesVisible
プロパティが設定されており、行と列、および行と列の間のギャップが表示されています。このプロパティは、GridPane
レイアウトを視覚的にデバッグする際に役立ちます。
ギャップ・プロパティを設定して、行と列の間のスペースを管理できます。パディング・プロパティを設定して、ノードとグリッド・ペインの端の間の距離を管理できます。垂直方向および水平方向の位置合せのプロパティを設定して、単一セル内の個々のコントロールの位置合せを管理できます。
例1-5では、図1-8に示されているグリッド・ペインを作成します。
例1-5 グリッド・ペインの作成
public GridPane addGridPane() { GridPane grid = new GridPane(); grid.setHgap(10); grid.setVgap(10); grid.setPadding(new Insets(0, 10, 0, 10)); // Category in column 2, row 1 Text category = new Text("Sales:"); category.setFont(Font.font("Arial", FontWeight.BOLD, 20)); grid.add(category, 1, 0); // Title in column 3, row 1 Text chartTitle = new Text("Current Year"); chartTitle.setFont(Font.font("Arial", FontWeight.BOLD, 20)); grid.add(chartTitle, 2, 0); // Subtitle in columns 2-3, row 2 Text chartSubtitle = new Text("Goods and Services"); grid.add(chartSubtitle, 1, 1, 2, 1); // House icon in column 1, rows 1-2 ImageView imageHouse = new ImageView( new Image(LayoutSample.class.getResourceAsStream("graphics/house.png"))); grid.add(imageHouse, 0, 0, 1, 2); // Left label in column 1 (bottom), row 3 Text goodsPercent = new Text("Goods\n80%"); GridPane.setValignment(goodsPercent, VPos.BOTTOM); grid.add(goodsPercent, 0, 2); // Chart in columns 2-3, row 3 ImageView imageChart = new ImageView( new Image(LayoutSample.class.getResourceAsStream("graphics/piechart.png"))); grid.add(imageChart, 1, 2, 2, 1); // Right label in column 4 (top), row 3 Text servicesPercent = new Text("Services\n20%"); GridPane.setValignment(servicesPercent, VPos.TOP); grid.add(servicesPercent, 3, 2); return grid; }
例1-1のsetCenter()
メソッドは、グリッド・ペインを枠線付きペインの中央のリージョンに追加します。この結果を図1-9に示します。
ウィンドウがサイズ変更されると、レイアウトの制約に応じて、グリッド・ペイン内のノードがサイズ変更されます。
FlowPane
FlowPane
レイアウト・ペイン内のノードは、連続してレイアウトされ、そのペインに設定された境界で折り返されます。ノードは、垂直方向(列)または水平方向(行)に一列に流し込みできます。垂直フロー・ペインでは、ペインの高さの境界で折り返されます。水平フロー・ペインでは、ペインの幅の境界で折り返されます。図1-10に、数値付きアイコンを使用したサンプル水平フロー・ペインを示します。これとは対照的に、垂直フロー・ペインでは、列1にページ1から4が含まれ、列2にページ5から8が含まれます。
ギャップ・プロパティを設定して、行と列の間のスペースを管理できます。パディング・プロパティを設定して、ノードとペインの端の間の距離を管理できます。例1-6では、一連のページ・アイコンを示す水平フロー・ペインを作成します。
例1-6 フロー・ペインの作成
public FlowPane addFlowPane() { FlowPane flow = new FlowPane(); flow.setPadding(new Insets(5, 0, 5, 0)); flow.setVgap(4); flow.setHgap(4); flow.setPrefWrapLength(170); // preferred width allows for two columns flow.setStyle("-fx-background-color: DAE6F3;"); ImageView pages[] = new ImageView[8]; for (int i=0; i<8; i++) { pages[i] = new ImageView( new Image(LayoutSample.class.getResourceAsStream( "graphics/chart_"+(i+1)+".png"))); flow.getChildren().add(pages[i]); } return flow; }
例1-1のsetRight()
メソッドは、フロー・ペインを枠線付きペインの右側のリージョンに追加します。この結果を図1-11に示します。
TilePane
タイル・ペインは、フロー・ペインに類似しています。TilePane
レイアウト・ペインは、各セル、つまりタイルが同じサイズであるグリッドに、すべてのノードを配置します。ノードは、水平方向(行)または垂直方向(列)に配置できます。水平方向のタイル表示では、タイル・ペインの幅の境界でタイルが折り返され、垂直方向のタイル表示では高さの境界でタイルが折り返されます。タイル・ペインの推奨サイズを設定するには、prefColumns
およびprefRows
プロパティを使用します。
ギャップ・プロパティを設定して、行と列の間のスペースを管理できます。パディング・プロパティを設定して、ノードとペインの端の間の距離を管理できます。
例1-7では、図1-10に示されているものと同じレイアウトを生成する水平タイル・ペインを作成します。
例1-7 タイル・ペインの作成
TilePane tile = new TilePane(); tile.setPadding(new Insets(5, 0, 5, 0)); tile.setVgap(4); tile.setHgap(4); tile.setPrefColumns(2); tile.setStyle("-fx-background-color: DAE6F3;"); ImageView pages[] = new ImageView[8]; for (int i=0; i<8; i++) { pages[i] = new ImageView( new Image(LayoutSample.class.getResourceAsStream( "graphics/chart_"+(i+1)+".png"))); tile.getChildren().add(pages[i]); }
AnchorPane
AnchorPane
レイアウト・ペインでは、ノードをペインの上部、下部、左側、右側または中央に固定できます。ウィンドウがサイズ変更されると、アンカー・ポイントに対して相対的にノードの位置が更新されます。ノードは複数の位置に固定でき、複数のノードを同じ位置に固定することもできます。図1-12に、GridPaneからのグリッド・ペインを上部に固定し、2つのボタンを含むHBox
ペインを下部および右側に固定したアンカー・ペインを示します。
例1-8では、ペインの上部に固定されたノードとペインの右下に固定されたノードを含むアンカー・ペインを作成します。例1-5で作成したグリッドを上部ノードとして使用します。
例1-8 アンカー・ペインの作成
public AnchorPane addAnchorPane(GridPane grid) { AnchorPane anchorpane = new AnchorPane(); Button buttonSave = new Button("Save"); Button buttonCancel = new Button("Cancel"); HBox hb = new HBox(); hb.setPadding(new Insets(0, 10, 10, 10)); hb.setSpacing(10); hb.getChildren().addAll(buttonSave, buttonCancel); anchorpane.getChildren().addAll(grid,hb); // Add grid from Example 1-5 AnchorPane.setBottomAnchor(hb, 8.0); AnchorPane.setRightAnchor(hb, 5.0); AnchorPane.setTopAnchor(grid, 10.0); return anchorpane; }
次の文は、枠線付きペインの中央のリージョンをアンカー・ペインに置き換えます。
border.setCenter(addAnchorPane(addGridPane()));
この結果を図1-13に示します。
ウィンドウがサイズ変更されると、アンカー・ポイントに従って、ペイン内のノードの位置が更新されます。図1-14は、ウィンドウのサイズが小さくなるにつれ、ペイン下部に固定されたボタンが売上げ情報に近づいていく様子を示しています。