javafx中设置舞台和场景的高度和宽度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18998671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:13:24  来源:igfitidea点击:

Set Height and Width of Stage and Scene in javafx

javajavafxstagescene

提问by Anvay

  • I develop one javafx application.
  • In my application there are two scenes and one stage.
  • In application the height and width for both scenes are same or constant.
  • so as per my research the height and width for scene remain constant which mention in the constructor but the scene adjust itself with height and width of stage.
  • when i lunch application with the height and width of stage which is different than the constant height and width of scene then scene adjust with stage.
  • but when at the run time when i apply the 2nd scene then scene is not adjust with height and width of stage.the height and width of scene remain constant.

  • so any solution?

  • 我开发了一个 javafx 应用程序。
  • 在我的应用程序中有两个场景和一个阶段。
  • 在应用中,两个场景的高度和宽度相同或恒定。
  • 所以根据我的研究,场景的高度和宽度保持不变,在构造函数中提到,但场景会根据舞台的高度和宽度自行调整。
  • 当我用舞台的高度和宽度与场景的恒定高度和宽度不同的午餐应用程序然后场景随着舞台调整。
  • 但是当我在运行时应用第二个场景时,场景不会随着舞台的高度和宽度进行调整。场景的高度和宽度保持不变。

  • 所以有什么解决办法吗?

采纳答案by shambhu

As I understand the problem above posted. I think the stage is good enough to set the preferred height and width as per the listener get the newer request to apply on the windows size. But it has some limitations, if you maximize or minimize the javaFX screen and will try to navigate to other screen then other screen will be having same window size but the scene content will distorted into the default height and width of it, e.g take a login and home scene in javafx (all scene is screated with fxml). Login.fxml is initialized by its controller. As you have mentioned that scene is initialized in constructor, so it must be the controller of the related fxml(as of now FXML is tight coupled with controller). You are going to set the scene size(height & width) in constructor itself.

据我了解上面发布的问题。我认为舞台足够好,可以根据听众设置首选的高度和宽度来获得适用于窗口大小的更新请求。但它有一些限制,如果您最大化或最小化 javaFX 屏幕并尝试导航到其他屏幕,则其他屏幕将具有相同的窗口大小,但场景内容将扭曲为其默认高度和宽度,例如登录和 javafx 中的家庭场景(所有场景都是用 fxml 创建的)。Login.fxml 由其控制器初始化。正如您所提到的,场景是在构造函数中初始化的,因此它必须是相关 fxml 的控制器(目前 FXML 与控制器紧密耦合)。您将在构造函数本身中设置场景大小(高度和宽度)。

1.) LoginController for login.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.) Same for HomeController --

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.) Main class

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);
    }
}

Just try to put Stage.hide() before Stage.show() in every controller. I hope this will help you out.

只需尝试将 Stage.hide() 放在每个控制器中的 Stage.show() 之前。我希望这会帮助你。

回答by Magcus

That is because the Stage adapts its size to the scene, unless explicitly instructed diferently...

那是因为舞台会根据场景调整其大小,除非另有明确指示......

To here is one solution:

这里是一种解决方案:

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

And a sample application:

和一个示例应用程序:

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);
    }
}

回答by Yevgeny Krasik

I know this is an old topic, but this (bug?) still persists in Java7u75.

我知道这是一个老话题,但是这个(错误?)在 Java7u75 中仍然存在。

I ran into the same issue... the solution offered by shambhu above does work, but results in a visible "window switching" effect:

我遇到了同样的问题......上面shambhu提供的解决方案确实有效,但会导致可见的“窗口切换”效果:

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

I found that the following code solves the problem (gets the stage to "refresh") without any visible effects:

我发现下面的代码解决了这个问题(让舞台“刷新”)而没有任何可见的效果:

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