Javafx-2 – JavaFX full screen – resizing elements based on screen size

Is there a way to make the full screen (resize if possible) instead of rearranging everything (in fact, it is rearranging elements, such as resizing, but the whole screen) to achieve full screen mode? (as in the usual game, change the screen resolution) so that the buttons and text increase to the size of the screen / window accordingly

How to delete messages and effects? Click "ESC" to exit full screen mode?

Edit: resize in this way

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

Solution

There are several ways to resize the UI

Scale by font size

You can use the in the scene style sheet Set - FX font size in root to scale all controls

For example, if you apply the following style sheet to your scene, the size of all controls will double (because the default font size is 13px)

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

The above work is scaling controls, which is good for things based entirely on control, but not so good for things based on graphics and shapes

Scale by transform

Apply a scale transformation swinging at (0,0) to the root node of your scene

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

In order to expand the game I developed that includes graphics and various shapes, I used a signal boxing technology to set the size of the game window to a constant aspect ratio (similar to the mailbox boxing: 9 screens when you watch a 4:3 TV program on TV 16)

The scenesizechangelistener in the following code listens to the change of scene size and scales the content of the scene to the available scene size

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

    letter@R_381_2419@(scene,root);
    stage.setFullScreen(true);
  }

  private void letter@R_381_2419@(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,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));
      }
    }
  }
}

This is a screenshot, you can see the mailbox and zoom effect The grass in the middle is the main game content screen, which can be zoomed up and down to fit the available screen area The outer wood texture provides a flexible size frame, filled with black mailbox, which is usually where you watch TV programs at different aspect ratios on your screen Please note that the background of the screenshot below is blurred on the title page, because I do so. When the game starts, the blur effect is deleted and the view is clear regardless of size

Window version:

Zoom full screen version:

You might think that the above scaling method might make everything blocky and pixelated, but it doesn't All fonts and controls are even and smooth All standard drawing and graphics commands and CSS based styles can be smoothed smoothly because they are vector based Even bitmap images are good because JavaFX uses fairly high quality filters when scaling images

One technique to achieve good image scaling is to provide high-resolution images so that when the screen expands, the JavaFX system has more raw data to work with For example, if your application's preferred window size is a quarter of the screen size, it contains 64 × 64 icon, but 128 × 128 icon, so that when the application is placed on the full screen and all elements are scaled, the scaler has more original pixel data samples for interpolation

Scaling is also the speed of hardware acceleration

It is impossible to delete the full screen exit message in JavaFX 2.2. It will be possible in JavaFX 8:

RT-15314 Allow trusted apps to disable the fullscreen overlay warning and disable the “Exit on ESC” behavior

This will be good because my game won't feel like "look at me - I look like a beta"

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>