JavaFX Stage分割のサンプルプログラム
JavaFXを使ってアプリを作る場合、ステージを分割してメニューバーやボタン、サイドメニューを配置するためにStageを分割すると便利です。
Paneを配置してWindowを分割し、サイズ変更や、図形のはみ出しを防ぐサンプルプログラムを紹介します。
Stageの分割
Paneを配置してStageを分割します
package tomojavalib.fx2;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class PaneBunkatuTest2 extends Application {
BorderPane basepane ;
Vbox toppane ;
FlowPane menupane ;
FlowPane menubar ;
FlowPane sidemenu ;
Pane centerpane ;
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
stage.setTitle("Pane分割テスト");
//paneの配置
basepane = new BorderPane();
Scene scene = new Scene(basepane, 640, 480);
toppane = new Vbox();
menupane = new FlowPane();
menubar = new FlowPane();
sidemenu = new FlowPane();
centerpane = new Pane();
toppane.getChildren().add( menubar );
toppane.getChildren().add( menupane );
basepane.setTop(toppane);
basepane.setLeft( sidemenu );
basepane.setCenter( centerpane );
menupane.setBackground(new Background(new BackgroundFill( Color.BLUE , CornerRadii.EMPTY , new Insets(1) )));
menubar.setBackground(new Background(new BackgroundFill( Color.BURLYWOOD , CornerRadii.EMPTY , new Insets(1) )));
toppane.setBackground(new Background(new BackgroundFill( Color.AQUA , CornerRadii.EMPTY , new Insets(1) )));
sidemenu.setBackground(new Background(new BackgroundFill( Color.AZURE , CornerRadii.EMPTY , new Insets(1) )));
centerpane.setBackground(new Background(new BackgroundFill( Color.BEIGE , CornerRadii.EMPTY , new Insets(1) )));
stage.setScene(scene);
setPaneSize();
stage.show();
}
/**各Paneのサイズを調整します*/
private void setPaneSize(){
menupane.setPrefHeight(50);
menubar.setPrefHeight(50);
System.out.println( basepane.getHeight()+" "+menupane.getPrefHeight()+" "+menubar.getPrefHeight());
sidemenu.setPrefWidth(150);
}
}
PaneやSceneの関係は下の図のような入れ子構造になります。
SubSceneの挿入
上のサンプルプログラムだと、図形等を描画した場合、はみ出してしまう場合があります。
下の例では、一番大きいCenterPaneに図形を描画していますが、Paneの範囲をはみ出して描画すると、他のPaneの上に描かれてしまいます。
こうした場合はSubSceneを挿入して、CenterPaneをその中に置くことで防げます。
サイズ変更の対応
SubSceneは大きさを指定する必要があるので、Stageのサイズを変更すると追従してくれません。
そこで、Stageのサイズが変わったらイベントを呼んでサイズを変更してあげます。
stage.widthProperty().addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneWidth, Number newSceneWidth) {
setPaneSize();
}
});
stage.heightProperty().addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneHeight, Number newSceneHeight) {
setPaneSize();
}
});
サンプルプログラム
下のサンプルプログラムを実行すると、このページ最上部の動画の実行結果が得られます。
package tomojavalib.fx2;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.SubScene;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Polyline;
import javafx.stage.Stage;
public class PaneBunkatuTest2 extends Application {
BorderPane basepane ;
Vbox toppane ;
FlowPane menupane ;
FlowPane menubar ;
FlowPane sidemenu ;
Pane centerpane ;
SubScene subscene;
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
stage.setTitle("Pane分割テスト");
//paneの配置
basepane = new BorderPane();
Scene scene = new Scene(basepane, 640, 480);
toppane = new Vbox();
menupane = new FlowPane();
menubar = new FlowPane();
sidemenu = new FlowPane();
centerpane = new Pane();
subscene = new SubScene(centerpane, 300, 300);
toppane.getChildren().add( menubar );
toppane.getChildren().add( menupane );
basepane.setTop(toppane);
basepane.setLeft( sidemenu );
basepane.setCenter( subscene );
//basepane.setCenter( centerpane );
//図形記入
Circle circle = new Circle(50);
circle.setFill(Color.WHITE);
circle.setStroke(Color.RED);
centerpane.getChildren().add( circle );
double[] d = new double[]{0,0,100,100};
Polyline polyline = new Polyline( d );
centerpane.getChildren().add( polyline );
polyline.setTranslateX(-50);
polyline.setTranslateY(50);
menupane.setBackground(new Background(new BackgroundFill( Color.BLUE , CornerRadii.EMPTY , new Insets(1) )));
menubar.setBackground(new Background(new BackgroundFill( Color.BURLYWOOD , CornerRadii.EMPTY , new Insets(1) )));
toppane.setBackground(new Background(new BackgroundFill( Color.AQUA , CornerRadii.EMPTY , new Insets(1) )));
sidemenu.setBackground(new Background(new BackgroundFill( Color.AZURE , CornerRadii.EMPTY , new Insets(1) )));
centerpane.setBackground(new Background(new BackgroundFill( Color.BEIGE , CornerRadii.EMPTY , new Insets(1) )));
stage.setScene(scene);
setPaneSize();
stage.show();
this.setEvent(stage);
}
/**各Paneのサイズを調整します*/
private void setPaneSize(){
menupane.setPrefHeight(50);
menubar.setPrefHeight(50);
System.out.println( basepane.getHeight()+" "+menupane.getPrefHeight()+" "+menubar.getPrefHeight());
subscene.setHeight( basepane.getHeight() -menupane.getPrefHeight()-menubar.getPrefHeight());
subscene.setWidth( basepane.getWidth()-sidemenu.getPrefWidth());
sidemenu.setPrefWidth(150);
}
/**イベント設定*/
private void setEvent( Stage stage ){
//大きさが変更されたときのイベント設定
stage.widthProperty().addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneWidth, Number newSceneWidth) {
setPaneSize();
}
});
stage.heightProperty().addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneHeight, Number newSceneHeight) {
setPaneSize();
}
});
}
}
最終更新日: 2019-01-22 09:04:14