如何在窗口之间切换时阻止JavaFx Slider控件重置为默认值

问题描述 投票:0回答:1

我在SceneBuilder中为javafx构建了一堆fxml窗口。当我在设置窗口和主菜单之间切换时,滑块(用于各种声级)重置为原始值,但是我希望它们保持上次窗口打开时的值。

我在初始化中尝试了设置值,并通过更改的类设置变量,并在启动时用于设置滑块,但这也不起作用。

The FXML

<!-- The slider code (scenebuilder forces me to choose a value) ->
<Slider fx:id="soundfxSlider" onMouseDragged="#updateSFX" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="50.0" />
<Slider fx:id="musicSlider" minorTickCount="1" onMouseDragged="#updateMusic" showTickLabels="true" showTickMarks="true" snapToTicks="true" />

The method for launching accessed by the main menu and other windows when switching

static void launchScreen(String fileName) {
        fileName = "/screens/" + fileName + ".fxml";
        try {
            Parent root = FXMLLoader.load(MainMenuController.class.getResource(fileName));
            Scene scene = new Scene(root);
            stage.setTitle("Fortress Combat");
            stage.setScene(scene);
            stage.show();
            stage.setOnCloseRequest(t -> {
                Platform.exit();
                System.exit(420);
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

The settings controller

public class SettingsController {

    @FXML // fx:id="soundfxSlider"
    private Slider soundfxSlider; // Value injected by FXMLLoader

    @FXML // fx:id="musicSlider"
    private Slider musicSlider; // Value injected by FXMLLoader

    @FXML
    void updateMusic(MouseEvent event) {
        double musicVolume =  musicSlider.getValue();
        //setMusicSlider(musicVolume);
        Launcher.adjustVolume(musicVolume);
    }

    @FXML
    void updateSFX(MouseEvent event) {
        double vol = soundfxSlider.getValue();
        //setSoundfxSlider(vol);
        Launcher.adjustSfx(vol);
    }

    private void setMusicSlider(double sliderVal) {
        musicSlider.setValue(sliderVal);
    }

    private void setSoundfxSlider(double sfxVal) {
        soundfxSlider.setValue(sfxVal);
    }

    @FXML
    void playTestSfx(ActionEvent event) {
        Launcher.playTestSFX();
    }

    @FXML
    void goBack(ActionEvent event) {
        Launcher.launchScreen("main_menu");
    }

    @FXML // This method is called by the FXMLLoader when initialization is complete
    void initialize() {
        assert soundfxSlider != null : "fx:id=\"soundfxSlider\" was not injected: check your FXML file 'settings.fxml'.";
        assert musicSlider != null : "fx:id=\"musicSlider\" was not injected: check your FXML file 'settings.fxml'.";
    }

如果没有给fxml中的滑块赋值,则默认值为0 - 似乎强制使用默认值,并且在切换窗口时它不会“记住”。

java javafx fxml scenebuilder
1个回答
1
投票

我相信我理解为什么在打开新窗口或者加载新窗口时始终在滑块上获得默认值。

如果您查看下面的代码,我们会看到您通过加载FXML并使用作为参数给出的名称来创建新父级,然后将新场景设置为您的舞台。要注意的关键是你创建了一个新的父级和场景,它不知道你在其他场景中设置滑块的任何值。

static void launchScreen(String fileName) {
    fileName = "/screens/" + fileName + ".fxml";
    try {
        Parent root =            
        FXMLLoader.load(MainMenuController.class.getResource(fileName));
        Scene scene = new Scene(root);
        stage.setTitle("Fortress Combat");
        stage.setScene(scene);
        stage.show();
        stage.setOnCloseRequest(t -> {
            Platform.exit();
            System.exit(420);
        });
    } catch (IOException e) {
        e.printStackTrace();
    }
}

一些建议:

  1. 保存实际场景,然后如果filename参数对应于已创建的场景,那么您可以真正“切换”场景而不是创建新场景。

下面是一个快速制作的示例,其中包含一个硬编码if语句,它只是为了向您展示我的意思,但我相信您可以更好地解决它并且重复代码更少。

private Scene sceneA;

static void launchScreen(String fileName) {
    if(fileName.equals("sceneA") && sceneA != null){
         /*if we want to open up sceneA and it has been created before (meaning it's not null) then open the already existing scene.*/
            stage.setTitle("Fortress Combat");
            stage.setScene(sceneA);
            stage.show();
            stage.setOnCloseRequest(t -> {
                Platform.exit();
                System.exit(420);
            });

    }else{
        fileName = "/screens/" + fileName + ".fxml";
        try {
            Parent root =            
            FXMLLoader.load(MainMenuController.class.getResource(fileName));
            Scene scene = new Scene(root);
            stage.setTitle("Fortress Combat");
            stage.setScene(scene);
            stage.show();
            stage.setOnCloseRequest(t -> {
                Platform.exit();
                System.exit(420);
            });
        } catch (IOException e) {
            e.printStackTrace();
        }   
    }   
}
  1. 建议2是将它们存储在某个地方,可能在某个处理程序类或文件中,如果您希望它们是持久的。
  2. 或者建议3可能是在控制器中声明一些静态变量,当滑块值发生变化时,你设置为滑块的值。然后,您可以通过访问静态变量在初始化方法中设置滑块值。

无论如何,那些是我的想法,我希望我可以得到一些帮助。让我们知道它是如何工作的:)

© www.soinside.com 2019 - 2024. All rights reserved.