【问题标题】:How to center a window properly in Java FX?如何在 Java FX 中正确居中窗口?
【发布时间】:2015-03-30 15:29:07
【问题描述】:

Java FX 提供 Window.centerOnScreen() 来——猜猜是什么——在屏幕上居中窗口。然而,Java FX 对“屏幕中心”的定义似乎是 (0.5x;0.33y)。我希望这是一个错误,但I was told it's not.

无论如何。有人想出一个干净简单的解决方案,说明如何在显示窗口之前将其居中?我的第一种方法会导致屏幕闪烁,因为必须先显示窗口,然后才能居中。

public static void centerOnScreen(Stage stage) {
  stage.centerOnScreen();
  stage.setY(stage.getY() * 3f / 2f);
}

更新: 我忘了提什么;我事先不知道窗口的大小,所以为了手动居中,我必须先显示它 - 是什么导致它闪烁一次。因此,我正在寻找一种解决方案来将其居中而不首先显示它 - 就像 Java FX 能够做到这一点,但是方法错误。

【问题讨论】:

    标签: javafx


    【解决方案1】:

    这是你在舞台可见之前的做法:

        double width = 640;
        double height = 480;
    
        Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
        stage.setX((screenBounds.getWidth() - width) / 2); 
        stage.setY((screenBounds.getHeight() - height) / 2);  
    
        final Scene scene = new Scene( new Group(), width, height);
        stage.setScene(scene);
        stage.show();
    

    在舞台可见之后,我。 e.您可以使用舞台的属性:

        double width = 640;
        double height = 480;
    
        final Scene scene = new Scene( new Group(), width, height);
        stage.setScene(scene);
        stage.show();
    
        Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
        stage.setX((screenBounds.getWidth() - stage.getWidth()) / 2); 
        stage.setY((screenBounds.getHeight() - stage.getHeight()) / 2);  
    

    如果您有多个屏幕,您可以使用Screen.getScreens() 方法返回的屏幕对象列表手动计算位置。

    【讨论】:

    • 谢谢,有没有办法在首先显示之前获取窗口的宽度/高度?我不知道它的大小。查看问题更新。
    • 你的反应很棒。但是,我只想为我们这些新人(包括我自己)添加一个注释。您需要确保导入是适合您的应用程序的 AWT 或 JavaFX。干杯
    【解决方案2】:

    响应值初始化的一般技巧是为属性创建一个侦听器,该侦听器在属性初始化时将其自身移除。所以你可以做

        Screen screen = Screen.getPrimary();
        Rectangle2D sbounds = screen.getBounds();
    
        double sw = sbounds.getWidth() ;
        double sh = sbounds.getHeight();
    
        listenToSizeInitialization(primaryStage.widthProperty(), 
                w -> primaryStage.setX(( sw - w) /2));
        listenToSizeInitialization(primaryStage.heightProperty(), 
                h -> primaryStage.setY(( sh - h) /2));
    
    
        primaryStage.show();
    

    private void listenToSizeInitialization(ObservableDoubleValue size, 
            DoubleConsumer handler) {
    
        ChangeListener<Number> listener = new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> obs, 
                    Number oldSize, Number newSize) {
                if (newSize.doubleValue() != Double.NaN) {
                    handler.accept(newSize.doubleValue());
                    size.removeListener(this);
                }
            }
        };
        size.addListener(listener);
    }
    

    【讨论】:

    • FWIW 我认为在 API 方法中完成的方式看起来更好——也许这就是我将自己定位在屏幕前的方式。但他们至少应该记录下他们正在做的事情。
    【解决方案3】:

    我知道这个帖子大约在三个半年前就得到了回答,但在我看来,每个人都忽略了这个问题。

    您只需要在stage.show() 之后键入stage.centerOnScreen();,因为如果您在代码执行一次之前编写它,然后它会进入其原始状态(这就是它在我脑海中的解释)。

    【讨论】:

    • 您似乎没有阅读并理解该问题。 centerOnScreen() 确实在屏幕上居中,这就是这篇文章的内容。
    • 对我有用。也许你需要更新你的 eclipse 文件
    【解决方案4】:

    对于此代码,您必须导入

    import java.awt.Dimension;
    import java.awt.Toolkit;
    

    然后

    Dimension d= Toolkit.getDefaultToolkit().getScreenSize(); // get screen size
    primaryStage.show(); //show stage because you wouldn't be able to get Height & width of the stage
    primaryStage.setX(d.width/2-(primaryStage.getWidth()/2));
    primaryStage.setY(d.height/2-(primaryStage.getHeight()/2));
    

    如果您想在显示该阶段之前执行此操作,则在 primaryStage.getWidth()/2 的位置将其替换为您将在场景构造函数中传递的高度。

    primaryStage.setX(d.width/2-(300/2));
    primaryStage.setY(d.height/2-(300/2));
    Scene scene = new Scene(root , 300 ,300);
    

    【讨论】:

      【解决方案5】:
      import javafx.application.Application;
      import javafx.geometry.Rectangle2D;
      import javafx.scene.Scene;
      import javafx.scene.layout.StackPane;
      import javafx.stage.Screen;
      import javafx.stage.Stage;
      
      public class Main extends Application {
      
          @Override
          public void start(Stage primaryStage) throws Exception{
      
              StackPane layout = new StackPane();
      
              primaryStage.setTitle("Kuristo: PT Test Admin System");
              primaryStage.setMinWidth(1280);
              primaryStage.setMinHeight(900);
              primaryStage.centerOnScreen();
      
              Scene scene = new Scene(layout);
              scene.getStylesheets().add("/styles/main.css");
              primaryStage.setScene(scene);
              primaryStage.show();
      
              Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
              primaryStage.setX((screenBounds.getWidth() - primaryStage.getWidth()) / 2);
              primaryStage.setY((screenBounds.getHeight() - primaryStage.getHeight()) / 2);
      
          }
      
          public static void main(String[] args) {
              launch(args);
          }
      }
      

      只是为了更新答案,我选择在显示窗口后实现居中。

      【讨论】:

      • 但问题明确针对“在显示之前”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-15
      • 2012-08-17
      • 1970-01-01
      • 1970-01-01
      • 2015-05-04
      • 2016-05-10
      • 2017-10-28
      相关资源
      最近更新 更多