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

Posted

技术标签:

【中文标题】在javafx中设置舞台和场景的高度和宽度【英文标题】:Set Height and Width of Stage and Scene in javafx 【发布时间】:2013-09-30 16:13:50 【问题描述】: 我开发了一个 javafx 应用程序。 在我的应用程序中有两个场景和一个阶段。 在应用程序中,两个场景的高度和宽度相同或恒定。 所以根据我的研究,场景的高度和宽度保持不变,在构造函数中提到,但场景会根据舞台的高度和宽度自行调整。 当我使用舞台的高度和宽度与场景的恒定高度和宽度不同的午餐应用程序时,然后根据舞台调整场景。

但是当我在运行时应用第二个场景时,场景不会根据舞台的高度和宽度进行调整。场景的高度和宽度保持不变。

所以有什么解决办法吗?

【问题讨论】:

舞台需要刷新但是怎么做? 【参考方案1】:

据我了解,上面发布的问题。我认为舞台已经足够好,可以根据侦听器设置首选的高度和宽度来获得更新的请求以应用于窗口大小。但它有一些限制,如果您最大化或最小化 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.hide() 放在 Stage.show() 之前。希望对您有所帮助。

【讨论】:

很好的答案!这是奇怪的事情(在JavaFX中)通过监听来更新大小......大小(场景具有高优先级)恕我直言。似乎必须提供自动模式。但代码工作正常。谢谢。【参考方案2】:

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

这里有一个解决方案:

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

【讨论】:

您发布的示例是正确的,将高度和宽度应用于舞台的概念也是正确的。但是如果您将背景图像应用于两个场景并在点击时更改舞台的大小(尝试不同的大小)两个按钮的事件然后你会发现实际问题。第二次场景不会随着舞台调整......所以我需要一种方法来刷新舞台。 stage.sizeToScene() 是正确的概念,但我希望场景可以根据舞台进行调整。【参考方案3】:

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

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

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

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

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

【讨论】:

以上是关于在javafx中设置舞台和场景的高度和宽度的主要内容,如果未能解决你的问题,请参考以下文章

如何在 colorbox iframe 中设置图像的高度和宽度?

在Xamarin Forms中设置TableView宽度和高度

如何在情节主题中设置宽度和高度?

如何在 Selenium WebDriver 中设置浏览器宽度和高度?

Swift:在 UIButton 类中设置宽度和高度

在 JCrop 中设置最大高度和最大宽度