Comment centrer correctement une fenêtre dans Java FX?


Java FX fournit une fenêtre.centerOnScreen () pour - deviner quoi-centrer une fenêtre sur un écran. CEPENDANT, la définition de Java FX de "centre d'un écran" semble être à (0.5 x;0.33 y). J'espérais que c'était un bug, mais m'a dit que ce n'est pas.

De toute façon. Quelqu'un a-t-il trouvé une solution propre et facile sur la façon de centrer une fenêtre avant de l'afficher? Ma première approche conduit à le scintillement de l'écran, depuis la fenêtre doit être affichée en premier, avant d'être égocentrique.

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

Mise à Jour: Ce que j'ai oublié de mentionner; Je ne connais pas la taille de la fenêtre à l'avance, donc pour la centrer manuellement, je dois d'abord l'afficher - ce qui la fait scintiller une fois. Je cherche donc une solution pour le centrer sans l'afficher d'abord - comme Java FX est capable de le faire, mais dans le mauvais sens.

Author: Michel Jung, 2015-03-30

4 answers

Voici comment vous le faites avant que la scène ne soit rendue visible:

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

Et ceci après que la scène a été rendue visible, c'est-à-dire que vous pouvez utiliser les propriétés de la scène:

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

Si vous avez plusieurs écrans, vous pouvez calculer la position manuellement en utilisant la liste des objets d'écran qui est renvoyée par l'écran .getScreens() méthode.

 9
Author: Roland, 2015-03-30 16:06:06

L'astuce générale pour répondre à l'initialisation d'une valeur est de créer un écouteur pour la propriété qui se supprime lorsque la propriété est initialisée. Donc, vous pouvez faire

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

Avec

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);
}
 3
Author: James_D, 2015-03-30 18:17:36

Pour ce code, vous devez importer

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

Puis

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

Si vous voulez le faire avant que cette étape ne soit affichée, alors à l'endroit de primaryStage.getWidth () / 2 remplacez-le par la hauteur que vous allez passer dans le constructeur scenes.

primaryStage.setX(d.width/2-(300/2));
primaryStage.setY(d.height/2-(300/2));
Scene scene = new Scene(root , 300 ,300);
 2
Author: Luser, 2016-09-20 04:54:01

Je sais que ce poste a été répondu il y a environ trois ans et demi, mais il me semble que tout le monde a négligé le problème.

Vous avez juste besoin de taper le stage.centerOnScreen(); juste après le stage.show() parce que si vous l'écrivez avant que le code ne soit exécuté une fois et ensuite il passe à son état d'origine(c'est ainsi que c'est expliqué dans ma tête).

 0
Author: Reddevil, 2017-11-09 15:29:32