切换根节点后,全屏模式的缩放效果消失

时间:2019-06-06 00:42:29

标签: java javafx fullscreen fxml

我试图在场景根之间切换,同时以全屏模式正确缩放它们。

我已经尝试过接受this question的答案中的代码,但是除非隐藏舞台然后在{{1}中重新显示它,否则我无法使用它切换到全屏模式} 方法。

最初,这至少会使“场景”选项正确缩放到全屏,但是当我返回标题“场景”时,效果消失了。

如何使该程序正确缩放每个场景?

我试图做一个最小,完整和可验证的示例,但是这很困难,因为我对JavaFX缺乏经验,并且由于将JavaFX与多个FXML文件一起使用的性质。

我相信我的问题的答案就在这里标记为“ MCVE类”的第一个代码框中。但是,如果要自己运行它,则必须将其他代码框放入其自己的文件中。

我没有包括CSS文件来节省空间,没有它们,这些场景可能看起来很奇怪。

如果您有任何意见或疑问,请告诉我,谢谢阅读。

MCVE类

letterbox()

标题屏幕控制器类

public class MCVE extends Application {

private final static Stage STAGE = new Stage();

private static boolean isFullscreen = false;

@Override
public void start(Stage primaryStage) throws Exception {

   Pane root = FXMLLoader.load(getClass().getResource("/fxml/title_screen.fxml"));

   Scene firstScene = new Scene(root, 1280.0, 800.0);

   STAGE.setScene(firstScene);

   STAGE.setTitle("Evil Wizard");
   STAGE.setResizable(false);

   STAGE.show();
}

public void activateOptionsScene() throws Exception {

   Pane root = FXMLLoader.load(getClass().getResource("/fxml/options_screen.fxml"));

   STAGE.getScene().setRoot(root);
}

public void activateTitleScene() throws Exception {

   Pane root = FXMLLoader.load(getClass().getResource("/fxml/title_screen.fxml"));

   STAGE.getScene().setRoot(root);
}

public void toggleFullscreen() {

   letterbox(STAGE.getScene(), (Pane) STAGE.getScene().getRoot());
   STAGE.setFullScreen(!isFullscreen);

   isFullscreen = !isFullscreen;
}

/**
 * Copied from
 * https://stackoverflow.com/questions/16606162/javafx-fullscreen-resizing-elements-based-upon-screen-size
 * <p>
 * author: jewelsea
 * date retrieved: 6-5-19
 * <p>
 * Resizes elements when switching between fullscreen and windowed mode.
 */
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;

   private 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;
      if (newWidth / newHeight > ratio)
         scaleFactor = newHeight / initHeight;
      else
         scaleFactor = newWidth / initWidth;

      System.out.println(scaleFactor + " " + (scaleFactor >= 1));

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

/**
 * Modified version of letterbox method from the same source as the above
 * static class. Forces application to hide and then show itself again.
 *
 * @param scene The Scene object to scale.
 * @param contentPane The Pane to scale.
 */
public void letterbox(final Scene scene, final Pane contentPane) {

   STAGE.hide();

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

   STAGE.setFullScreen(!Organizer.isFullscreen());
   Organizer.setIsFullscreen(Organizer.isFullscreen());

   STAGE.show();
}

}

选项屏幕控制器类

package controllers;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import main.MCVE;

public class TitleScreenController {

@FXML
private Button optionsButton;

public void goToOptionsScene() throws Exception {

   new MCVE().activateOptionsScene();
}

}

title_screen.fxml

package controllers;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import main.MCVE;

public class OptionsScreenController {

@FXML
private Button returnButton;

public void toggleFullscreen() {

   new MCVE().toggleFullscreen();
}

public void returnToTitleScreen()  throws Exception {

   new MCVE().activateTitleScene();
}
}

options_screen.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1280.0" style="-fx-background-color: BLACK;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.TitleScreenController">
   <children>
      <Label layoutX="310.0" layoutY="105.0" scaleX="2.0" scaleY="2.0" text="Evil Wizard" textFill="WHITE" underline="true">
         <font>
            <Font name="Dumbledor 1" size="96.0" />
         </font>
      </Label>
      <VBox fillWidth="false" layoutX="279.0" layoutY="373.0" prefHeight="325.0" prefWidth="500.0" spacing="15.0" stylesheets="@../css/buttons_sidebar.css">
         <children>
            <Button fx:id="continueButton" alignment="CENTER" mnemonicParsing="false" prefHeight="0.0" prefWidth="999.0" text="   Continue   " visible="false">
               <font>
                  <Font name="Caladea Bold" size="22.0" />
               </font>
            </Button>
            <Button fx:id="startButton" alignment="CENTER" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#startGame" text="   Start   ">
               <font>
                  <Font name="Charis SIL Bold" size="22.0" />
               </font>
            </Button>
            <Button fx:id="loadButton" alignment="CENTER" layoutX="10.0" layoutY="123.0" mnemonicParsing="false" text="   Load   ">
               <font>
                  <Font name="Charis SIL Bold" size="22.0" />
               </font>
            </Button>
            <Button fx:id="optionsButton" alignment="CENTER" layoutX="55.0" layoutY="184.0" mnemonicParsing="false" onAction="#goToOptionsScene" text="   Options   ">
               <font>
                  <Font name="Charis SIL Bold" size="22.0" />
               </font>
            </Button>
            <Button fx:id="exitButton" alignment="CENTER" layoutX="10.0" layoutY="236.0" mnemonicParsing="false" onAction="#exitGame" text="   Exit   ">
               <font>
                  <Font name="Charis SIL Bold" size="22.0" />
               </font>
            </Button>
         </children>
      </VBox>
   </children>
</Pane>

0 个答案:

没有答案