- 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/
仅使用POSIX shell 的特性,是否有一个“简单命令”,它什么也不做,也不改变$? 的值。人们通常描述:作为 shell 的无操作命令,但这总是设置 $?为零,所以这不是我想要的。 这是生成 s
我需要保留当前的 GlBlendFunc 以便在我做一些工作后可以恢复它。似乎这不是可以用 GLPushAttrib 保存的属性之一,还有其他类似的方法可以用来保存状态吗? 最佳答案 glGet与
我目前正致力于创建 Fuseki 三重存储浏览器的项目。我需要可视化 TripleStore 中的所有数据并使应用程序可浏览。唯一的问题是 QuerySolution 遗漏了三元组中的“”。 如果我使
我知道没有必要保留委托(delegate),以避免保留循环。我在一次采访中碰巧遇到了一个问题,“如果保留了 appDelegate 会怎样?”。我对此没有答案,并根据我的知识在这里寻求答案。谢谢 最佳
我正在用 C 编写第一个更严肃的程序,但我陷入了困境。我需要将此列表排序为不同的单独文件,因此它看起来像这样: BE30B Berlin 2014-04-02 Gale 02 BE30B Berlin
我有 4 个页面,我使用 ajax 和 historyPopState 在它们之间进行更改。但是有一个问题,因为页面非常不同,它们使用不同的样式表和脚本。我可以一遍又一遍地下载它们,但我想问一下是否有
我有一个表单,其中包含从一个表创建的多行(与其他表没有关系)。当我保存表单时,我所做的每项更改都会保存,但数据库中确实有一个额外的空行。请参阅下文(希望)了解所有必要的信息。 PropertyAddi
我正在编写一个可以在 Canvas 上绘制气泡的应用程序。我有 MainActivity,它的布局是一个简单的 LinearLayout,我将其用作 fragment 的容器。当我在 Canvas 上
我想弄清楚为什么我通过这段代码得到 EXC_BAD_ACESS。我没有线索。谁能帮帮我。 - (void)loadJsonFile:(NSString*)fileName { NSError
我正在编写一个代码,它将遍历单词中的每个单词,在字典中查找它们,然后将字典值附加到计数器。但是,如果我打印计数器,我只会从我的 if 语句中获取最后一个数字(如果有的话)。如果我将 print cou
抱歉,标题有点困惑。 我想隐藏这些选择选项,只在用户选择按钮时显示。一旦用户选择了一个按钮,我希望选择字段将继续显示......但是如果用户选择了不同的按钮,我想从以前的选择中重置所选的选项并炫耀。
>>> t = "first%s\n" >>> t = t %("second") >>> print t firstsecond 无论如何我可以保留最后的“\n”并得到“firstsecond\n”
我试图弄清楚如何更改 if 语句中的变量并使其保持全局不变。 用户输入:!change Hi var A = "Hello" if (msg.content.includes ('!change'))
您好,我有一个关于在重新创建 Activity 时保留 fragment 的问题。我听说一种方法是在 onCreate 方法中使用 setRetainFragment(true) 。问题是——这与跟踪
我想知道是否有人可以帮助我解决下面代码中的内存管理问题。我对 rootController 特别感兴趣,它是在我执行 initWithRootViewController 时被保留还是在窗口 addS
我想确保我在这里正确理解了内存管理。是否有任何特殊原因在这里使用其中一种 assignCurrentDate 方法而不是另一种方法?此外,所有这些都不会导致内存泄漏,对吗? 在 .h 中我们有: NS
我对 Angular2 删除尾部斜杠有疑问。我已经设置了我的 dotnet 核心应用程序来添加它们,但是一旦加载了 js,它们就会被删除。 在 Angular2 中甚至可能吗? (我的客户需要它,所以
local_settings.py 反模式的原因之一是把 SECRET_KEY, AWS设置文件中的键等值有问题: secret 通常应该是这样的: secret !将它们保存在版本控制中意味着拥有存
import('./A'); import('./B'); import('./C'); export class Person {}; A、B 和 C 是纯 JS (es5) 库,它们使用全局 wi
df 是一个测试数据框,其中我只想保留 Hits 列中包含 | 字符的行和行其中包含 hits(即 Hit1、Hit2 等)以及 Hits 列中的空白单元格。 df 从开始 (^) 到结束 ($)
我是一名优秀的程序员,十分优秀!