JavaFX fullscreen - redimensionnement des éléments en fonction de la taille de l'écran

y a-t-il un moyen de faire le plein écran(et si possible de redimensionner aussi) au lieu de tout réarranger (en fait, ce qu'il fait est de réarranger les éléments comme redimensionner mais à l'écran entier) pour faire un mode plein écran réel? (comme les jeux qui font habituellement changer la résolution de l'écran), de sorte que les boutons et le texte se développe en fonction de la taille de l'écran/fenêtre

Aussi, comment puis-je supprimer le message et l'effet sur cliquez sur la touche "esc" pour quitter le plein écran mode?

EDIT: utilisez cette façon de faire redimensionnable

@Override public void start(Stage stage) throws Exception{
    final int initWidth = 720;      //initial width
    final int initHeight = 1080;    //initial height
    final Pane root = new Pane();   //necessary evil

    Pane controller = new CtrlMainMenu();   //initial view
    controller.setPrefWidth(initWidth);     //if not initialized
    controller.setPrefHeight(initHeight);   //if not initialized
    root.getChildren().add(controller);     //necessary evil

    Scale scale = new Scale(1, 1, 0, 0);
    scale.xProperty().bind(root.widthProperty().divide(initWidth));     //must match with the one in the controller
    scale.yProperty().bind(root.heightProperty().divide(initHeight));   //must match with the one in the controller
    root.getTransforms().add(scale);

    final Scene scene = new Scene(root, initWidth, initHeight);
    stage.setScene(scene);
    stage.setResizable(true);
    stage.show();

    //add listener for the use of scene.setRoot()
    scene.rootProperty().addListener(new ChangeListener<Parent>(){
        @Override public void changed(ObservableValue<? extends Parent> arg0, Parent oldValue, Parent newValue){
            scene.rootProperty().removeListener(this);
            scene.setRoot(root);
            ((Region)newValue).setPrefWidth(initWidth);     //make sure is a Region!
            ((Region)newValue).setPrefHeight(initHeight);   //make sure is a Region!
            root.getChildren().clear();
            root.getChildren().add(newValue);
            scene.rootProperty().addListener(this);
        }
    });
}
12
demandé sur jewelsea 2013-05-17 13:51:48

2 réponses

il y a plusieurs façons de redimensionner votre UI.

échelle selon la taille de la police

vous pouvez mettre à l'échelle tous les contrôles en mettant -fx-font-size dans le .root de la feuille de style de votre scène.

par exemple, si vous appliquez la feuille de style suivante à votre scène, alors toutes les commandes seront doublées en taille (parce que la taille de police par défaut est 13px).

.racine { -FX-font-size: 26px; }

les contrôles ci-dessus fonctionneront à l'échelle, ce qui est bien pour les choses qui sont complètement basées sur le contrôle, mais pas si bon pour les choses qui sont basées sur le graphisme et la forme.

mise à l'Échelle par Transformer

Appliquer Échelle transform pivotez à (0,0) sur le noeud racine de votre scène.

Scale scale = new Scale(scaleFactor, scaleFactor);
scale.setPivotX(0);
scale.setPivotY(0);
scene.getRoot().getTransforms().setAll(scale);

pour mettre à l'échelle un jeu que j'ai développé qui comprend des graphiques et des formes diverses, j'ai utilisé une technique de boxe de la lettre qui a dimensionné la fenêtre de jeu à un rapport d'aspect constant, (similaire à la boxe de la lettre vous voyez quand vous regardez une émission de télévision 4:3 sur un écran 16:9).

le SceneSizeChangeListener dans le code ci-dessous écoute pour les changements à la taille de la scène et les échelles le contenu de la scène appropriée à la taille de la scène disponible.

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;
import org.jewelsea.games.supersnake.layout.LayoutController;

import java.io.IOException;
import java.util.ResourceBundle;

/* Main JavaFX application class */
public class SuperSnake extends Application {
  public static void main(String[] args) { launch(args); }

  @Override public void start(final Stage stage) throws IOException {
    FXMLLoader loader = new FXMLLoader(
        getClass().getResource("layout/layout.fxml"),
        ResourceBundle.getBundle("org.jewelsea.games.supersnake.layout.text")
    );
    Pane root = (Pane) loader.load();

    GameManager.instance().setLayoutController(loader.<LayoutController>getController());

    Scene scene = new Scene(new Group(root));
    stage.setScene(scene);
    stage.show();

    GameManager.instance().showMenu();

    letterbox(scene, root);
    stage.setFullScreen(true);
  }

  private void letterbox(final Scene scene, final Pane contentPane) {
    final double initWidth  = scene.getWidth();
    final double initHeight = scene.getHeight();
    final double ratio      = initWidth / initHeight;

    SceneSizeChangeListener sizeListener = new SceneSizeChangeListener(scene, ratio, initHeight, initWidth, contentPane);
    scene.widthProperty().addListener(sizeListener);
    scene.heightProperty().addListener(sizeListener);
  }

  private static class SceneSizeChangeListener implements ChangeListener<Number> {
    private final Scene scene;
    private final double ratio;
    private final double initHeight;
    private final double initWidth;
    private final Pane contentPane;

    public SceneSizeChangeListener(Scene scene, double ratio, double initHeight, double initWidth, Pane contentPane) {
      this.scene = scene;
      this.ratio = ratio;
      this.initHeight = initHeight;
      this.initWidth = initWidth;
      this.contentPane = contentPane;
    }

    @Override
    public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {
      final double newWidth  = scene.getWidth();
      final double newHeight = scene.getHeight();

      double scaleFactor =
          newWidth / newHeight > ratio
              ? newHeight / initHeight
              : newWidth / initWidth;

      if (scaleFactor >= 1) {
        Scale scale = new Scale(scaleFactor, scaleFactor);
        scale.setPivotX(0);
        scale.setPivotY(0);
        scene.getRoot().getTransforms().setAll(scale);

        contentPane.setPrefWidth (newWidth  / scaleFactor);
        contentPane.setPrefHeight(newHeight / scaleFactor);
      } else {
        contentPane.setPrefWidth (Math.max(initWidth,  newWidth));
        contentPane.setPrefHeight(Math.max(initHeight, newHeight));
      }
    }
  }
}

Voici une capture d'écran où vous pouvez voir l'effet de boîte aux lettres et de mise à l'échelle. L'herbe verte dans le milieu est l'écran principal de contenu de jeu et les échelles de haut en bas pour s'adapter à la zone d'écran disponible. La texture du bois autour de la outside fournit une bordure de taille flexible qui remplit la zone où les barres de boîtes aux lettres noires seraient normalement si vous regardiez une émission de télévision à un rapport d'aspect différent de votre écran. Notez que le fond dans la capture d'écran ci-dessous est flou à la page de titre parce que je le fais ainsi, lorsque le jeu commence, l'effet flou est enlevé et la vue est croquante quelle que soit la taille.

version fenêtrée:

letterbox

échelle plein écran version:

letterbox-full-screen

vous pourriez penser que la méthode de mise à l'échelle ci-dessus pourrait faire tout va blocky et pixelated, mais il ne le fait pas. Toutes les polices et tous les contrôles se dimensionnent en douceur. Toutes les commandes graphiques et de dessin standard et les styles basés sur css se dimensionnent en douceur car ils sont tous basés sur des vecteurs. Même les images bitmapées ont une bonne échelle parce que JavaFX utilise des filtres de qualité assez élevée lors de la mise à l'échelle des images.

Une astuce pour obtenir une bonne mise à l'échelle sur les images, c'est fournir des images de haute résolution, de sorte que lorsque l'écran évolue en Charge le système a plus de données brutes. Par exemple, si la taille de fenêtre préférée pour une application est le quart de la taille de l'écran et qu'elle contient une icône 64x64, utilisez plutôt une icône 128x128, de sorte que lorsque l'application est mise en plein écran et tous les éléments mis à l'échelle, le scaler a plus d'échantillons de données brutes de pixel à utiliser pour l'interpolation des valeurs.

la mise à l'échelle est aussi rapide que l'accélération matérielle.

comment puis-je supprimer le message et l'effet sur cliquez sur la touche "esc" pour quitter le mode plein écran?

il n'est pas possible de supprimer le message de sortie plein écran dans JavaFX 2.2, il sera possible dans JavaFX 8:

RT-15314 permettent aux applications de confiance de désactiver l'avertissement de superposition plein écran et désactiver le comportement "Exit on ESC"

Il sera agréable quand c'est fait, parce que mon jeux n'aura pas que "regardez-moi - je ressemble à un bêta" se sentent à leur sujet.

14
répondu jewelsea 2013-05-17 11:58:19

"Aussi, comment puis-je supprimer le message et l'effet sur cliquez sur la touche "esc" pour quitter le mode plein écran?"

Utilisez ce code:

stage.setFullScreenExitHint("");

il va changer le message de chaîne de caractères "appuyez sur Esc pour quitter le mode plein écran" en chaîne vide de sorte qu'il ne se présentera pas.

3
répondu Ratul Bin Tazul 2016-12-28 19:01:05