Saltar al contenido

JavaFX fullscreen: cambiar el tamaño de los elementos según el tamaño de la pantalla

Sé libre de compartir nuestros tutoriales y códigos en tus redes sociales, necesitamos de tu ayuda para aumentar nuestra comunidad.

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 su escena.

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

.raíz -fx-font-size: 26px;

Lo anterior funcionará para escalar los 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.

Escala por transformación

Aplique una transformación de escala girada 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 formato de caja de letras que ajustaba el tamaño de la ventana del juego a una relación de aspecto constante (similar a la caja de letras que ves cuando miras un programa de televisión 4:3 en una pantalla de 16 :9 pantalla).

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 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.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 
    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 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 donde puede ver cómo se aplica el formato de pantalla ancha y la escala. La hierba verde en el medio es la pantalla principal de contenido del juego y se amplía y reduce 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 en 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 del título porque lo hago así, cuando comienza el juego, 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 escalada:

buzón de pantalla completa

Podrías pensar que el método de escalado anterior podría hacer que todo se vuelva en bloques y pixelado, pero no es así. Todas las fuentes y controles escalan sin problemas. Todos los comandos gráficos y de dibujo 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 escalan bien porque JavaFX usa filtros de calidad bastante alta al escalar las imágenes.

Un truco para obtener un buen escalado de 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 con los que trabajar. Por ejemplo, si el tamaño de ventana preferido para una aplicación es una cuarta parte 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 escalan, el escalador tiene más sin procesar. muestras de datos de píxeles para usar para interpolar valores.

La escala también es rápida ya que está acelerada por hardware.

¿Cómo puedo eliminar el mensaje y el efecto al hacer clic en “esc”? key 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 eso esté hecho, porque entonces mis juegos no tendrán esa sensación de “mírame, parezco una beta”.

“También, ¿cómo puedo eliminar el mensaje y el efecto al hacer clic en “esc” key para salir del modo de pantalla completa?”

Usa este código:

stage.setFullScreenExitHint("");

Cambiará el string mensaje “Presione Esc para salir del modo de pantalla completa” en vacío string por lo que no aparecerá.

Reseñas y valoraciones de la guía

¡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 *