title: Setting native resolution in JavaFX
body: <p>I'd like to set the native resolution in a game that I'm working on: I'm aware this can be done in AWT. But cannot find any documentation on a way to achieve this using Glass Windowing Toolkit. I'd rather not get into AWT at all if anyone knows a better way, as I wonder how performant this solution might be.</p>
  
  <p>I'm also aware of JFXPanels, and have spent some time experimenting with these. My game can scale to accommodate different screen sizes and aspects, but if a player wants to lower the amount of pixels being rendered by the GPU, I want to offer his this option by lowering the screen resolution. Rather than the player having to do this in the OS before running the game. This is fairly standard in most games.</p>
  
  <p>My experiments with JFXPanels work fine but it seems I only get access to a JavaFX scene, and not to a Stage: my game often uses Stages for Modal dialogs. In this example, a JavaFX Scene object is embedded into a JFrame. My question is, how can I then obtain a way to add various modals etc into my game?</p>
  
  <p>I want to work in JavaFX not Swing, and would prefer to avoid using Swing whilst coding, as it's slow firing up the AWT fullscreen. I also want to avoid using Swing layout managers to cope with my modal windows (which sounds awful).</p>
  
  <p>I hesitantly post this "hack" to get JavaFX running in a AWT resolution altered 
  screen size, in the hope someone has better way of doing this. (The "blankingFrame" is to hide all the white screens and flickers as the screen resolution changes.)</p>
  
  <pre><code>import javafx.application.Application;
  import javafx.application.Platform;
  import javafx.embed.swing.JFXPanel;
  import javafx.scene.Group;
  import javafx.scene.Scene;
  import javafx.scene.text.Font;
  import javafx.scene.text.Text;
  import javafx.stage.Stage;
  
  import javax.swing.*;
  import java.awt.*;
  import java.awt.event.WindowAdapter;
  import java.awt.event.WindowEvent;
  
  
  
    //alt-F4 to exit once in full screen mode
  public class DisplaysFX extends Application {
  
  private final static boolean RUN_AS_AWT = true;
  private JFrame blankingFrame;
  private JFrame jFrame;
  private JFXPanel fxPanel;
  
  public static void main(String[] args) {
      if (RUN_AS_AWT) {
          new DisplaysFX().runTest();
      } else {
          Application.launch(DisplaysFX.class, args);
      }
  }
  
  @Override
  public void start(Stage primaryStage) {
      Scene s = startFXScene();
      primaryStage.setScene(s);
      primaryStage.show();
  }
  
  private void initAndShowGUI() {
      fxPanel = new JFXPanel();
      jFrame.add(fxPanel);
      Platform.runLater(() -&gt; initFX(fxPanel));
  }
  
  private void initFX(JFXPanel fxPanel) {
      Scene scene = startFXScene();
      fxPanel.setScene(scene);
      fxPanel.setVisible(true);
  }
  
  private Scene startFXScene() {
      Group root = new Group();
      Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
      javafx.scene.shape.Rectangle r = new javafx.scene.shape.Rectangle(0, 0, dimension.width, dimension.height);
      r.setFill(javafx.scene.paint.Color.PURPLE);
      root.getChildren().add(r);
      Scene scene = new Scene(root);
      Text text = new Text();
      text.setFont(new Font(100));
      text.setText("I'm some text in JavaFX");
      text.setX(((dimension.width / 2) - text.getLayoutBounds().getWidth() / 2));
      text.setY(((dimension.height / 2) - text.getLayoutBounds().getHeight() / 2));
      root.getChildren().add(text);
      return (scene);
  }
  
  private void runTest() {
      new Thread(() -&gt; createBlankJFrame()).start();
  
      try {
          Thread.sleep(500);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
  
      GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment();
      GraphicsDevice[] devices = g.getScreenDevices();
  
      SwingUtilities.invokeLater(() -&gt; {
          jFrame = new JFrame();
          jFrame.setVisible(false);
          jFrame.getContentPane().setBackground(Color.BLACK);
          jFrame.setUndecorated(true);
          jFrame.setResizable(false);
          jFrame.setExtendedState(Frame.MAXIMIZED_BOTH);
  
          jFrame.addWindowListener(new WindowAdapter() {
              @Override
              public void windowClosing(WindowEvent event) {
                  SwingUtilities.invokeLater(() -&gt; {
                      Window w = devices[0].getFullScreenWindow();
                      if (w != null) {
                          w.dispose();
                      }
                      devices[0].setFullScreenWindow(null);
                      jFrame.dispose();
                      blankingFrame.dispose();
                      System.exit(0);
                  });
              }
          });
  
          devices[0].setFullScreenWindow(jFrame);
          DisplayMode displayMode = new DisplayMode(1920, 1080, 32, 60); //change this if want to alter your screen to a different size
          devices[0].setDisplayMode(displayMode);
      });
  
  
      try {
          Thread.sleep(100);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
  
      new Thread(() -&gt; SwingUtilities.invokeLater(() -&gt; initAndShowGUI())).start();
  }
  
  private void createBlankJFrame() {
      SwingUtilities.invokeLater(() -&gt; {
          Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
          blankingFrame = new JFrame();
          blankingFrame.getContentPane().setBackground(Color.BLACK);
          blankingFrame.setMinimumSize(screenSize);
          blankingFrame.setUndecorated(true);
          blankingFrame.setResizable(false);
          blankingFrame.setVisible(true);
      });
      }
  }
  </code></pre>