Как остановить сброс элементов управления JavaFx Slider к их значениям по умолчанию при переключении между окнами - PullRequest
0 голосов
/ 26 марта 2019

У меня есть несколько окон fxml, которые я построил в SceneBuilder для javafx. Когда я переключаюсь между окном настроек и главным меню, ползунки (для разных уровней звука) возвращаются к своим первоначальным значениям, однако я бы хотел, чтобы они сохранили значения, которые были в последний раз, когда окно было открыто.

Я пробовал значения настроек при инициализации и настраивал переменную через класс, который изменяется и используется для установки ползунков при его запуске, но это тоже не сработало.

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" />

Способ запуска, доступный из главного меню и других окон при переключении

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

Контроллер настроек

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 - кажется, что значение по умолчанию принудительно, и оно не «запоминает», когда переключаются окна.

1 Ответ

1 голос
/ 26 марта 2019

Мне кажется, я понимаю, почему вы получаете значения по умолчанию на вашем слайдере все время, когда вы открываете новое окно или, скорее, загружаете новое окно.

Если вы посмотрите на приведенный ниже код, мы увидим, что вы создаете нового родителя, загружая ваш FXML с именем, которое задается в качестве аргумента, после чего вы устанавливаете новую сцену на свою сцену. Из этого следует отметить, что вы создаете a нового родителя и сцену, которая не имеет представления о каких-либо значениях, которые устанавливают ваши ползунки в других сценах.

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. Сохраните реальную сцену, а затем, если аргумент имени файла соответствует уже созданной сцене, тогда вы действительно можете «переключить» сцену вместо создания новой.

Ниже приведен быстро сделанный пример с жестко закодированным оператором 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, которое может заключаться в объявлении некоторых статических переменных в вашем контроллере, которые вы устанавливаете в значения ваших ползунков, когда значения ползунков изменились. Затем вы можете установить значения ползунка в вашем методе initialize, используя ваши статические переменные.

В любом случае, это были мои мысли, и я надеюсь, что смогу чем-нибудь помочь. Дайте нам знать, как это работает:)

...