web-dev-qa-db-ja.com

javafxでステージとシーンの高さと幅を設定する

  • 1つのjavafxアプリケーションを開発します。
  • 私のアプリケーションでは、2つのシーンと1つのステージがあります。
  • アプリケーションでは、両方のシーンの高さと幅は同じか一定です。
  • 私の研究によると、シーンの高さと幅はコンストラクターで言及されている一定のままですが、シーンはステージの高さと幅で調整されます。
  • シーンの一定の高さと幅とは異なるステージの高さと幅のアプリケーションをランチすると、ステージでシーンが調整されます。
  • しかし、実行時に2番目のシーンを適用すると、シーンはステージの高さと幅で調整されません。シーンの高さと幅は一定のままです。

  • 解決策はありますか?

13
Anvay

私が理解したように、上記の問題は投稿されました。リスナーは、ウィンドウサイズに適用する新しい要求を取得するため、好みの高さと幅を設定するのに十分な段階だと思います。ただし、javaFX画面を最大化または最小化し、他の画面に移動しようとすると、他の画面のウィンドウサイズは同じになりますが、シーンコンテンツはデフォルトの高さと幅に歪んでしまいます。 javafxのホームシーン(すべてのシーンはfxmlで作成されます)。 Login.fxmlは、コントローラーによって初期化されます。シーンはコンストラクターで初期化されると述べたように、関連するfxmlのコントローラーである必要があります(現在、FXMLはコントローラーと密結合しています)。コンストラクター自体でシーンのサイズ(高さと幅)を設定します。

1.)login.fxmlのLoginController

 import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;

    import Java.io.IOException;

    class LoginController  {

        private Stage stage;
        private Scene scene;
        private Parent parent;
        @FXML  
        private Button gotoHomeButton;        

        public LoginController()  throws Exception {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/login.fxml"));
            fxmlLoader.setController(this);
            try {
                parent = (Parent) fxmlLoader.load();
                // set height and width here for this login scene
                scene = new Scene(parent, 1000, 800);
            } catch (IOException ex) {
                System.out.println("Error displaying login window");
                throw new RuntimeException(ex);
            }
        }

        // create a launcher method for this. Here I am going to take like below--
        public void launchLoginScene(Stage stage) {
           this.stage = stage;
            stage.setScene(scene);
            stage.setResizable(true);

            stage.widthProperty().addListener(new ChangeListener<Number>() {
                @Override
                public void changed(ObservableValue<? extends Number> observableValue, Number number, Number number2) {
                    setCurrentWidthToStage(number2); 
                }
            });

            stage.heightProperty().addListener(new ChangeListener<Number>() {
                @Override
                public void changed(ObservableValue<? extends Number> observableValue, Number number, Number number2) {
                    setCurrentHeightToStage(number2);
                }
            });

            //Don't forget to add below code in every controller
            stage.hide();
            stage.show();

        }

         @FXML
        public void authenticateUser(ActionEvent actionEvent) { 

        // write your logic to authenticate user


         // 
         new HomeController().displayHomeScreen(stage);

        } 

        private void setCurrentWidthToStage(Number number2) {
            stage.setWidth((double) number2);
        }

        private void setCurrentHeightToStage(Number number2) {
            stage.setHeight((double) number2);
        }
    }

2.)HomeControllerでも同じ-

public class HomeController {

    private Parent parent;
    private Stage stage;
    private Scene scene;


    public HomeController (){
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/home.fxml"));
        fxmlLoader.setController(this);
        try {
             parent = (Parent) fxmlLoader.load();
                // set height and width here for this home scene
                scene = new Scene(parent, 1000, 800);
        } catch (IOException e) {
         // manage the exception
        }
    }

    public void displayHomeScreen(Stage stage){
        this.stage = stage;
        stage.setScene(scene); 

        // Must write
        stage.hide()
        stage.show();
    }
}

3.)メインクラス

import javafx.application.Application;

import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        new LoginController().launchLoginScene(primaryStage);
    }


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

すべてのコントローラーでStage.show()の前にStage.hide()を配置してください。これがあなたのお役に立てば幸いです。

7
shambhu

明示的に別の指示がない限り、ステージはシーンに合わせてサイズを調整するためです...

ここに1つの解決策があります:

stage.setScene(scene2);
stage.setHeight(1000);
stage.setWidth(1000);

サンプルアプリケーション:

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class Test extends Application {

    @Override
    public void start(final Stage stage) throws Exception {

        AnchorPane anchor1 = new AnchorPane();
        final Scene scene1 = new Scene(anchor1, 250, 250);
        Button boton1 = new Button();
        anchor1.getChildren().add(boton1);

        AnchorPane anchor2 = new AnchorPane();
        final Scene scene2 = new Scene(anchor2, 500, 500);
        Button boton2 = new Button();
        anchor2.getChildren().add(boton2);

        boton2.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                // TODO Auto-generated method stub
                stage.setScene(scene1);
                stage.setHeight(1000);
                stage.setWidth(1000);
            }
        });

        boton1.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                // TODO Auto-generated method stub
                stage.setScene(scene2);
                stage.setHeight(1000);
                stage.setWidth(1000);
            }
        });
        stage.setScene(scene1);
        stage.show();
    }

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

これは古いトピックであることは知っていますが、これ(バグ?)はまだJava7u75に残っています。

私は同じ問題に遭遇しました...上記のshambhuが提供する解決策は機能しますが、目に見える「ウィンドウ切り替え」効果をもたらします。

stage.hide();
stage.show();

次のコードは、目に見える効果なしで問題を解決する(ステージを「更新」する)ことがわかりました。

final boolean resizable = stage.isResizable();
stage.setResizable(!resizable);
stage.setResizable(resizable);
2
Yevgeny Krasik