Saltar al contenido

Pantalla completa de JavaFX: cambio de tamaño de elementos según el tamaño de la pantalla

Solución:

Hay un par de formas de cambiar el tamaño de la interfaz de usuario.

Escalar por tamaño de fuente

Puede escalar todos los controles configurando -fx-font-size en el .root de la hoja de estilo de tu escena.

Por ejemplo, si aplica la siguiente hoja de estilo a su escena, todos los controles duplicarán su tamaño (porque el tamaño de fuente predeterminado es 13px).

.root {-fx-font-size: 26px; }

Lo anterior funcionará para escalar controles, lo cual está bien para cosas que están completamente basadas en controles, pero no tan bueno para cosas que están basadas en gráficos y formas.

Escalar por transformación

Aplique una transformación de escala pivotada en (0,0) al nodo raíz de su escena.

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

Para escalar un juego que desarrollé que incluye gráficos y varias formas, utilicé una técnica de cuadro de letras que dimensionó la ventana del juego a una relación de aspecto constante (similar al cuadro de letras que ves cuando ves un programa de televisión 4: 3 en un 16 : Pantalla 9).

El SceneSizeChangeListener en el código a continuación escucha los cambios en el tamaño de la escena y escala el contenido de la escena de acuerdo con el tamaño de la escena 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));
      }
    }
  }
}

Aquí hay una captura de pantalla en la que puede ver el efecto del formato de pantalla ancha y la escala. La hierba verde en el medio es la pantalla principal de contenido del juego y se escala hacia arriba y hacia abajo para adaptarse al área de pantalla disponible. La textura de madera alrededor del exterior proporciona un borde de tamaño flexible que llena el área donde normalmente estarían las barras negras del buzón si estuviera viendo un programa de televisión con una relación de aspecto diferente a la de su pantalla. Tenga en cuenta que el fondo en la captura de pantalla a continuación está borroso en la página de título porque lo hago así, cuando el juego comienza, el efecto de desenfoque se elimina y la vista es nítida independientemente del tamaño.

Versión con ventana:

buzón

Versión de pantalla completa a escala:

buzón de pantalla completa

Puede pensar que el método de escala anterior puede hacer que todo salga en bloques y pixelado, pero no es así. Todas las fuentes y controles se escalan sin problemas. Todos los comandos de dibujo y gráficos estándar y los estilos basados ​​en CSS se escalan sin problemas, ya que todos están basados ​​en vectores. Incluso las imágenes de mapa de bits se escalan bien porque JavaFX utiliza filtros de calidad bastante alta al escalar las imágenes.

Un truco para obtener una buena escala en las imágenes es proporcionar imágenes de alta resolución, de modo que cuando la pantalla se amplíe, el sistema JavaFX tenga más datos sin procesar para trabajar. Por ejemplo, si el tamaño de ventana preferido para una aplicación es un cuarto del tamaño de la pantalla y contiene un ícono de 64×64, en su lugar use un ícono de 128×128, de modo que cuando la aplicación se coloque en pantalla completa y todos los elementos se escalen, el escalador tenga más contenido sin procesar. muestras de datos de píxeles que se utilizarán para interpolar valores.

El escalado también es rápido, ya que se acelera por hardware.

¿Cómo puedo eliminar el mensaje y el efecto al hacer clic en la tecla “esc” para salir del modo de pantalla completa?

No es posible eliminar el mensaje de salida de pantalla completa en JavaFX 2.2, será posible en JavaFX 8:

RT-15314 Permitir que las aplicaciones de confianza deshabiliten la advertencia de superposición de pantalla completa y deshabiliten el comportamiento “Salir en ESC”

Será bueno cuando termine, porque entonces mis juegos no tendrán esa sensación de “mírame, parezco una beta”.

“Además, ¿cómo puedo eliminar el mensaje y el efecto al hacer clic en la tecla” esc “para salir del modo de pantalla completa?”

Utilice este código:

stage.setFullScreenExitHint("");

Cambiará el mensaje de cadena “Presione Esc para salir del modo de pantalla completa” a una cadena vacía para que no se muestre.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *