読者です 読者をやめる 読者になる 読者になる

takeda_san’s blog

JavaFXとDeeplearning4jを頑張る方向。

setResizableをfalseにすると、不要な余白が生じる問題

唐突に始まるJavaFX記事。

事象

Scene Builder上でのFXMLプレビューと実際にコントローラーを実装して起動したときの画面サイズが違う気がする。

もともと、この事象に気が付いたのはStageが保持しているSceneを別のSceneで差し替えて画面を切り替えるような処理を書いているとき。
なぜか差し替え処理の後に画面サイズが一回り小さくなる。
デバッグしていくうちに原因が分かった。

原因

Stageが持つ、resizablePropertyをfalseにしているとSceneの外側に余白ができるっぽい。

Stage (JavaFX 8)

問題が再現するコードは以下の通り。
ボタンを押したときに、ステージのサイズをSceneの大きさに合わせるメソッドを走らせる。
不要な余白(マージン)があればステージ幅が小さくなるはずだ。

わかりやすくするためにボタンの大きさとSceneの大きさは同じにしている。

package application;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            HBox root = new HBox();

            // Sceneと同じ大きさのボタンを作る
            Button button = new Button("sizeToScene");
            button.setPrefWidth(400); // 幅400px
            button.setPrefHeight(400); // 高さ400px

            // ステージのサイズをシーンの大きさに合わせる
            button.setOnAction(event -> {
                primaryStage.sizeToScene();
            });
            root.getChildren().add(button);

            // シーンとステージの表示
            Scene scene = new Scene(root, 400, 400);
            primaryStage.setScene(scene);
            primaryStage.setResizable(false);
            primaryStage.show();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

実行結果がこちら。

sizeToScene実行前

f:id:takeda_san:20170227222120p:plain

sizeToScene実行後

f:id:takeda_san:20170227222125p:plain

起動時に右下に12~3pxぐらいの余白があるが、sizeToSceneをすると消えている。
ちなみに「primaryStage.setResizable(false);」をtrueにすると余白はできない。

対応策

ここにもある通り、面倒だが毎回、sizeToSceneで余白を消すしかないようだ。
しかもこの件、バグらしく前から要望が出ているものの直されてないとのこと。
(この質問自体、結構前のものだ)

stackoverflow.com

レイアウトの都合上、リサイズされたくない画面って結構あるとおもうんですけどね。
Java 9では直っていることを祈っています。
ちなみに実行環境はWindows + JRE 1.8.0_121でした。