我试图在场景根之间切换,同时以全屏模式正确缩放它们。
我已经尝试过接受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>