- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
重要信息和方法
所以我有这个方法(目前还不完整),其唯一目的是更改每个屏幕中的背景图像。这是执行此操作的方法。
if(optionButton1.isArmed())
{
optionButton1.setOnMouseClicked(e-> Optionmenu.setId("BlueBackground1"));
}
else if(optionButton2.isArmed())
{
optionButton2.setOnMouseClicked(e-> Optionmenu.setId("BlueBackground2"));
}
else
{
optionButton3.setOnMouseClicked(e-> Optionmenu.setId("BlueBackground3"));
}
所以这段代码目前所做的是检查按下和释放了哪个按钮,并将旧 ID 更改为新 ID。一旦将其更改为新 ID,它将更改 FXML 文件中的 ID,然后 FXML 文件将进入我的 css 文件并查找与新 ID 匹配的 ID。
现在这个 FXML 变量在我的 Controller 类之一 (OptionscreenController) 中,变量的名称是 Optionmenu。在我的 Controller 类中看起来像这样
@FXML private StackPane Optionmenu;
这意味着 optionmenu 是此方法更改的 FXML 文件的主根。
我面临的挑战之一是找到一种方法将所有节点或根节点引入此类,并尽可能更改这些节点的 ID。
这是我解决这个问题的尝试:
try
{
FXMLLoader myLoader = new FXMLLoader(getClass().getResource(MillionaireTriviaGame.MAIN));
myLoader.load();
mainMenu = myLoader.getRoot();
mainMenu.setId("BlueBackground2")
}
catch (IOException ex)
{
Logger.getLogger(OptionscreenController.class.getName()).log(Level.SEVERE, null, ex);
}
我想做的是加载一个 FXML 文件和主文件旁边的另一个 FXML 文件,使用 getRoot() 获取 FXML 文件中的对象,将其添加到一个变量具有相同的 fx:id 并使用 setId 更改其旧 ID。
现在这样做有两个问题:首先,这样做会调用初始化为运行的覆盖方法,无论如何(每个 Controller 都必须有这个方法)。所以我说,好吧,我不会使用 FXMLLoader.load()。我会立即直接使用 getRoot()。原来它将 FXML 变量设置为空。
我面临的最后一个挑战是在用户从一个屏幕切换到另一个屏幕时保持对每个背景所做的更改。
这些是我目前面临的挑战。
代码时间
我认为您首先需要了解的是我如何从一个屏幕过渡到另一个屏幕。会有很多代码要看,所以如果可以的话请多多包涵。
ScreenNavigator类-用于加载和设置屏幕
package millionairetriviagame;
import java.io.IOException;
import java.util.HashMap;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.StackPane;
import javafx.util.Duration;
public class ScreenNavigator extends StackPane
{
private HashMap<String, Node> screens = new HashMap<>();
public ScreenNavigator()
{
super();
}
public void addScreen(String name, Node screen)
{
screens.put(name, screen);
}
public Node getScreen(String name)
{
return screens.get(name);
}
public boolean loadScreen(String name, String resource)
{
try
{
FXMLLoader myLoader = new FXMLLoader(getClass().getResource(resource));
Parent loadscreen = myLoader.load();
ControllingScreens ScreenController = myLoader.getController();
ScreenController.setScreenParent(this);
addScreen(name, loadscreen);
return true;
}
catch (IOException e)
{
System.out.println(e.getMessage());
return false;
}
}
public boolean setScreen(String name)
{
if (screens.get(name) != null)
{
if (!getChildren().isEmpty())
{
Timeline transition = new Timeline(new KeyFrame(Duration.seconds(0.5), (ActionEvent event) ->
{
getChildren().clear();
getChildren().add(screens.get(name));
}));
transition.play();
MillionaireTriviaGame.fade(true);
}
else
{
getChildren().add(screens.get(name));
MillionaireTriviaGame.fade(false);
}
return true;
}
else
{
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error Dialog");
alert.setHeaderText(null);
alert.setContentText("The screen wasn't able to load.");
alert.showAndWait();
return false;
}
}
}
接下来是使用这个类的主类。
主类
package millionairetriviagame;
import java.util.Optional;
import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.image.Image;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class MillionaireTriviaGame extends Application
{
private static final Rectangle fillRectangle = new Rectangle();
public static final String MAINSCREENID = "main";
public static final String MAIN = "MenulayoutFXML.fxml";
public static final String OPTIONSCREENID = "option";
public static final String OPTION = "Optionscreen.fxml";
@Override
public void start(Stage menuStage) throws Exception
{
ScreenNavigator controller = new ScreenNavigator();
controller.loadScreen(MillionaireTriviaGame.MAINSCREENID, MillionaireTriviaGame.MAIN);
controller.setScreen(MillionaireTriviaGame.MAINSCREENID);
StackPane root = new StackPane();
root.getChildren().addAll(controller, fillRectangle);
root.setAlignment(Pos.TOP_CENTER);
Scene scene = new Scene(root, 1366, 768);
fillRectangle.setWidth(scene.getWidth());
fillRectangle.setHeight(scene.getHeight());
fillRectangle.setDisable(true);
menuStage.setScene(scene);
menuStage.setOnCloseRequest(e ->
{
Alert exitConfirmation = new Alert(Alert.AlertType.CONFIRMATION, "Are you sure you want to exit this application?");
exitConfirmation.setTitle("Exit Application");
exitConfirmation.setHeaderText("Confirm Exit");
Optional<ButtonType> choice = exitConfirmation.showAndWait();
if (choice.get() == ButtonType.OK)
{
menuStage.close();
}
else
{
e.consume();
}
});
menuStage.setTitle("Let's play who wants to be a millionaire");
menuStage.getIcons().add(new Image(getClass().getResource("/millionairetriviagame/ImageFiles/gameIcon.png").toExternalForm()));
menuStage.setFullScreen(true);
menuStage.show();
}
public static void main(String[] args)
{
launch(args);
}
public static void fade(boolean inOut)
{
FadeTransition ft = new FadeTransition(Duration.seconds(5), fillRectangle);
ft.setFromValue(1);
ft.setToValue(0);
if (inOut)
{
ft.setDuration(Duration.seconds(0.5));
ft.setFromValue(0);
ft.setToValue(1);
ft.setAutoReverse(true);
ft.setCycleCount(2);
}
ft.play();
}
}
接下来是负责更改所有屏幕的背景图像的 Controller 类。
选项屏幕 Controller
package millionairetriviagame;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
public class OptionscreenController implements Initializable, ControllingScreens
{
private ScreenNavigator controller;
private MediaPlayer optionMenuPlayer;
@FXML private Button backToMain;
private BooleanProperty isDisabled;
@FXML private StackPane Optionmenu;
@FXML private Button optionButton1;
@FXML private Button optionButton2;
@FXML private Button optionButton3;
@Override
public void initialize(URL url, ResourceBundle rb)
{
configureProperties();
playSong();
}
private void configureProperties()
{
isDisabled = new SimpleBooleanProperty();
backToMain.disableProperty().bind(isDisabled);
}
@Override
public void setScreenParent(ScreenNavigator parentScreen)
{
controller = parentScreen;
}
private void playSong()
{
Media optionIntroTheme = new Media(getClass().getResource("/millionairetriviagame/AudioFiles/OptionMenuMusic.mp3").toExternalForm());
optionMenuPlayer = new MediaPlayer(optionIntroTheme);
optionMenuPlayer.setAutoPlay(true);
optionMenuPlayer.setVolume(0.1);
optionMenuPlayer.setCycleCount(MediaPlayer.INDEFINITE);
}
@FXML private void changeBackgroundScreen() // This is the method where it all happens.
{
if(optionButton1.isArmed())
{
optionButton1.setOnMouseClicked(e-> Optionmenu.setId("BlueBackground1"));
}
else if(optionButton2.isArmed())
{
optionButton2.setOnMouseClicked(e-> Optionmenu.setId("BlueBackground2"));
}
else
{
optionButton3.setOnMouseClicked(e-> Optionmenu.setId("BlueBackground3"));
}
}
@FXML private void goToTheMainMenu()
{
isDisabled.setValue(true);
optionMenuPlayer.stop();
controller.loadScreen(MillionaireTriviaGame.MAINSCREENID, MillionaireTriviaGame.MAIN);
controller.setScreen(MillionaireTriviaGame.MAINSCREENID);
}
}
以及控制显示哪个画面的接口(interface)(每个controller都有这个方法)。
package millionairetriviagame;
public interface ControllingScreens
{
public void setScreenParent(ScreenNavigator parentScreen);
}
最佳答案
解决方案
这是我想出的一个解决方案:
在我的 screenNavigator 类中,我添加了这个方法:
private String getBackgroundId()
{
BufferedReader br = null;
String backgroundId = "";
try
{
br = new BufferedReader(new FileReader("Background.txt"));
backgroundId = br.readLine();
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
if (br != null)
{
br.close();
}
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
}
return backgroundId;
}
然后在同一个类中,我在loadScreen方法中添加了两行代码
mainMenu = myLoader.getRoot();
mainMenu.setId(getBackgroundId());
这里是覆盖文件的方法。
private void changeBackgroundId(String backgroundId)
{
BufferedWriter bw = null;
try
{
bw = new BufferedWriter(new FileWriter("Background.txt", false));
bw.write(backgroundId);
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
if (bw != null)
{
bw.close();
}
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
}
}
这是 changeBackgroundScreen 现在的样子
@FXML private void changeBackgroundScreen()
{
if(optionButton1.isArmed())
{
optionButton1.setOnMouseClicked(e-> Optionmenu.setId("BlueBackground1"));
changeBackgroundId("BlueBackground1");
}
else if(optionButton2.isArmed())
{
optionButton2.setOnMouseClicked(e-> Optionmenu.setId("BlueBackground2"));
changeBackgroundId("BlueBackground2");
}
else
{
optionButton3.setOnMouseClicked(e-> Optionmenu.setId("BlueBackground3"));
changeBackgroundId("BlueBackground3");
}
}
解释
此解决方案的工作方式是,每次我从一个屏幕转换到另一个屏幕时,我将加载 backgroundId 文件中的唯一行,即 css 文件中的 id。一旦用户单击按钮更改背景(查看 optionScreenController 类),我将写入文件并使用新 Id 覆盖旧 Id,以便每个屏幕都将加载新背景。对于我的两个问题,这是一个不错的解决方案。如果其他人认为他们可以改进此解决方案,请改进。
关于java - 如何更改所有屏幕上的背景图像并保留更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29690239/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!