JavaFX fullscreen – ridimensionamento degli elementi in base alle dimensioni dello schermo

C’è un modo per rendere a schermo intero (e se ansible anche il ridimensionamento) invece di riorganizzare tutto (in realtà quello che fa è riorganizzare gli elementi come il ridimensionamento ma su tutto lo schermo) per creare una modalità a schermo intero reale? (come i giochi, quello che di solito si fa è cambiare la risoluzione dello schermo), in modo che i pulsanti e il testo crescano in base alle dimensioni dello schermo / finestra

Inoltre, come posso rimuovere il messaggio e l’effetto facendo clic sul tasto “esc” per uscire dalla modalità a schermo intero?

EDIT: utilizzare questo modo per rendere ridimensionabile

@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(){ @Override public void changed(ObservableValue 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); } }); } 

Ci sono un paio di modi per ridimensionare l’interfaccia utente.

Ridimensiona in base alla dimensione del carattere

Puoi ridimensionare tutti i controlli impostando -fx-font-size nella .root del foglio di stile della scena.

Ad esempio, se si applica il seguente foglio di stile alla scena, tutti i controlli verranno raddoppiati in termini di dimensioni (poiché la dimensione predefinita del carattere è 13 px).

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

Quanto sopra funzionerà per ridimensionare i controlli, il che va bene per le cose che sono completamente basate sul controllo, ma non così buone per le cose che sono basate sulla grafica e sulla forma.

Scala per trasformazione

Applicare una trasformazione di scala ruotata su (0,0) al nodo radice della scena.

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

Per scalare un gioco che ho sviluppato che include grafica e varie forms, ho usato una tecnica di boxe per le lettere che ha dimensionato la finestra di gioco in proporzioni costanti, (simile alla boxe delle lettere che vedi quando guardi uno show televisivo 4: 3 su un 16 : 9 schermo).

SceneSizeChangeListener nel codice seguente ascolta le modifiche alle dimensioni della scena e ridimensiona il contenuto della scena in base alla dimensione della scena disponibile.

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

Ecco uno screenshot in cui è ansible vedere il letterboxing e il ridimensionamento in corso. L’erba verde al centro è la schermata principale del gioco e si adatta su e giù per adattarsi all’area dello schermo disponibile. La struttura di legno attorno all’esterno fornisce un bordo di dimensioni flessibili che riempie l’area in cui le barre nere letterbox sarebbero normalmente se si stesse guardando un programma TV con proporzioni diverse sullo schermo. Nota che lo sfondo nello screenshot qui sotto è sfocato nel frontespizio perché lo faccio così, quando il gioco inizia, l’effetto sfocatura viene rimosso e la vista è nitida indipendentemente dalle dimensioni.

Versione con finestra:

letterbox

Versione a schermo intero ridimensionato:

letterbox-a schermo intero

Potresti pensare che il metodo di ridimensionamento in alto potrebbe rendere tutto bloccato e pixelato, ma non è così. Tutti i font e i controlli si adattano perfettamente. Tutti i disegni standard e i comandi grafici e gli stili basati su CSS si adattano in modo uniforms poiché sono tutti basati su vettori. Anche le immagini bitmap sono scalabili perché JavaFX utilizza filtri di qualità piuttosto elevata durante il ridimensionamento delle immagini.

Un trucco per ottenere un buon ridimensionamento delle immagini è quello di fornire immagini ad alta risoluzione, in modo che quando lo schermo si ingrandisce, il sistema JavaFX ha più dati grezzi su cui lavorare. Ad esempio, se la dimensione della finestra preferita per un’app è pari a un quarto delle dimensioni dello schermo e contiene un’icona 64×64, usa invece un’icona 128×128, in modo che quando l’app viene messa a schermo intero e tutti gli elementi ridimensionati, lo scaler presenta più grezzo campioni di dati pixel da utilizzare per valori interpolati.

Il ridimensionamento è anche veloce in quanto è accelerato dall’hardware.

come posso rimuovere il messaggio e l’effetto cliccando sul tasto “esc” per uscire dalla modalità a schermo intero?

Non è ansible rimuovere il messaggio di uscita a schermo intero in JavaFX 2.2, sarà ansible in JavaFX 8:

RT-15314 Consenti alle applicazioni attendibili di distriggersre l’avviso di sovrapposizione a schermo intero e di distriggersre il comportamento “Esci su ESC”

Sarà bello quando ciò sarà fatto, perché allora i miei giochi non avranno quel feeling “guardami – sembro una beta” su di loro.

“Inoltre, come posso rimuovere il messaggio e l’effetto facendo clic sul tasto” esc “per uscire dalla modalità a schermo intero?”

Usa questo codice:

 stage.setFullScreenExitHint(""); 

Cambierà il messaggio di stringa “Premi Esc per uscire dalla modalità a schermo intero” in una stringa vuota in modo che non venga visualizzato.