如何在Java FX中正确居中窗口?

时间:2015-03-30 15:29:08

标签: javafx

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能够做到这一点一样,但这是错误的方式。

5 个答案:

答案 0 :(得分:11)

这是你在舞台可见之前的方式:

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

这个阶段在可见之后,我。即你可以使用舞台的属性:

    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()方法返回的Screen对象列表手动计算位置。

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

此代码必须导入

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

如果你想在show stage之前做这个,那么在primaryStage.getWidth()/ 2的地方用你在场景构造函数中传递的高度替换它。

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

答案 3 :(得分:0)

我知道这个帖子已经有大约三年半的时间了,但在我看来,每个人都忽略了这个问题。

你只需要在stage.centerOnScreen();之后输入stage.show(),因为如果你在代码执行一次之前编写它然后它会进入原始状态(这就是我在头)。

答案 4 :(得分:0)

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

为获得更新的答案,我选择在显示窗口之后实施居中。