JavaFX2DSceneと3DSceneを同時に表示する方法
JavaFXで3Dの形状を表示しながら2Dで設定値を表示したいので、1つのウインドウに2Dと3Dを同時に表示するプログラムを作ってみました。
左側にVboxのPaneを置き、その中にテキストを並べて表示。右には3DGropを置いて、立方体、カメラ、照明を配置しています。
ウインドウ構造は下のような形になります。
基本になるStage、Scene、Paneの中にSubSceneを2つ配置して、それぞれに2Dと3Dに仕立てています。
SubSceneはサイズを指定して作成する必要があるので、SubSceneを作ったのち、最後にStageのサイズを合わせました。
これだとウインドウのサイズを変えた時にSubsceneのサイズが変わらないのでちょっと困ります。
Stageのサイズ変更時にSubSceneのサイズを行うようにする必要がありそうですね。
下のコードを実行すると、以下のように表示されます。
実行結果
サンプルプログラム
package tomojavalib.fx;
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.SubScene;
import javafx.scene.control.Button;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.*;
import javafx.stage.Stage;
/**
*SubSceneを用いて 2Dsceneと3Dsceneを表示する
* */
public class App13 extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
//3Dシーンを作成
Pane pane3d = new Pane();
SubScene ss3d = make3dSubScene();
ss3d.setFill(Color.BLACK);
// 2Dシーンを作成
SubScene ss2d = make2dSubScene();
ss2d.setFill(Color.AQUA);
//親シーンを作成してサブシーンを配置
Pane pane = new Pane();
pane.getChildren().add( ss3d );
pane.getChildren().add( ss2d );
ss3d.relocate( ss2d.getWidth() , 0 );
Scene scene = new Scene( pane );
stage.setScene(scene);
//Stageの設定
//タイトルの表示
stage.setTitle("SubScene試験");
//開くときのサイズ
stage.sizeToScene();
stage.show();
}
private SubScene make2dSubScene(){
Vbox pane = new Vbox();
pane.setPadding( new Insets(10,10,10,10) );
SubScene ss2d = new SubScene(pane, 100, 480);
Text[] t = new Text[8];
for (int i = 0; i < t.length; i++) {
t[i] = new Text( "テキスト"+i );
pane.getChildren().add( t[i] );
}
return ss2d;
}
private SubScene make3dSubScene(){
Group group = new Group();
//箱を置く
Box box = new Box( 10 , 10 , 10 );
box.setRotationAxis( new Point3D( 1.5 , 1.5 , 1.5 ) );
box.setRotate( 45.0 );
group.getChildren().add( box );
//
カメラ
楽天 を置く
Camera camera = new PerspectiveCamera( true );
camera.setTranslateZ( -50.0 );
group.getChildren().add( camera );
//点光源を置く
LightBase light = new PointLight();
light.setTranslateX( 30.0 );
light.setTranslateY( -30.0 );
light.setTranslateZ( -30.0 );
group.getChildren().add( light );
SubScene ss3d = new SubScene(group, 540, 480);
ss3d.setCamera( camera );
return ss3d;
}
}
ウインドウサイズに合わせてSubSceneサイズを変える
いろいろやってみて、追加文を入れることにしました。
まずはstart()の中に下記イベント処理を追記。
stage.widthProperty().addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneWidth, Number newSceneWidth) {
redraw();
}
});
stage.heightProperty().addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneHeight, Number newSceneHeight) {
redraw();
}
});
そして呼び出されたredraw()の中でサイズを変更
private void redraw(){
System.out.println("サイズ変更");
ss2d.setHeight(pane.getHeight());
ss3d.relocate( ss2d.getWidth() , 0 );
ss3d.setHeight(pane.getHeight());
ss3d.setWidth(pane.getWidth() - ss2d.getWidth() );
}
全体ではこうなります。
SubSceneサイズ変更サンプルプログラム
package tomojavalib.fx;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.SubScene;
import javafx.scene.control.Button;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.*;
import javafx.stage.Stage;
/**
*SubSceneを用いて 2Dsceneと3Dsceneを表示する
*windowサイズ変更に対応
* */
public class App14 extends Application {
SubScene ss3d;
SubScene ss2d;
Pane pane;
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start( Stage stage ) throws Exception {
//3Dシーンを作成
Pane pane3d = new Pane();
ss3d = make3dSubScene();
ss3d.setFill(Color.BLACK);
// 2Dシーンを作成
ss2d = make2dSubScene();
ss2d.setFill(Color.AQUA);
//親シーンを作成してサブシーンを配置
pane = new Pane();
pane.getChildren().add( ss3d );
pane.getChildren().add( ss2d );
ss3d.relocate( ss2d.getWidth() , 0 );
Scene scene = new Scene( pane );
stage.setScene(scene);
//Stageの設定
//タイトルの表示
stage.setTitle("SubSceneサイズ変更試験");
stage.widthProperty().addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneWidth, Number newSceneWidth) {
redraw();
}
});
stage.heightProperty().addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneHeight, Number newSceneHeight) {
redraw();
}
});
//開くときのサイズ
stage.sizeToScene();
stage.show();
}
private void redraw(){
System.out.println("サイズ変更");
ss2d.setHeight(pane.getHeight());
ss3d.relocate( ss2d.getWidth() , 0 );
ss3d.setHeight(pane.getHeight());
ss3d.setWidth(pane.getWidth() - ss2d.getWidth() );
}
private SubScene make2dSubScene(){
VBox pane = new VBox();
pane.setPadding( new Insets(10,10,10,10) );
SubScene ss2d = new SubScene(pane, 100, 480);
Text[] t = new Text[8];
for (int i = 0; i < t.length; i++) {
t[i] = new Text( "テキスト"+i );
pane.getChildren().add( t[i] );
}
return ss2d;
}
private SubScene make3dSubScene(){
Group group = new Group();
//箱を置く
Box box = new Box( 10 , 10 , 10 );
box.setRotationAxis( new Point3D( 1.5 , 1.5 , 1.5 ) );
box.setRotate( 45.0 );
group.getChildren().add( box );
// カメラを置く
Camera camera = new PerspectiveCamera( true );
camera.setTranslateZ( -50.0 );
group.getChildren().add( camera );
//点光源を置く
LightBase light = new PointLight();
light.setTranslateX( 30.0 );
light.setTranslateY( -30.0 );
light.setTranslateZ( -30.0 );
group.getChildren().add( light );
SubScene ss3d = new SubScene(group, 540, 480);
ss3d.setCamera( camera );
return ss3d;
}
}
実行結果
上のコードを実行すると、下のようになります。
最終更新日: 2019-02-18 08:26:23