Почему Java не показывает кнопки на второй сцене - PullRequest
2 голосов
/ 27 апреля 2019

У меня есть три сцены в моей программе. Когда я запускаю его, я вижу первую сцену со всеми кнопками. Затем, когда я иду ко второй сцене, я вижу только ярлык, кнопки не отображаются. На третьей сцене все работает нормально, я вижу ярлык и кнопки.

Итак, вопрос в том, почему мои кнопки не отображаются на моей второй сцене?

Я попытался изменить порядок настройки кнопок и сцен, чтобы сцена 2 (громкость) была третьей сценой, а третья сцена (разрешение) - второй сценой. Каждый раз, когда вторая сцена не показывает кнопки.

package view.options;

import javafx.application.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Options extends Application {
    Scene optionsMenu, volumeMenu, resolutionMenu;

    // Create the labels
    Label optionslabel= new Label("This is the options scene");
    Label volumelabel= new Label("This is the volume scene");
    Label resolutionlabel= new Label("This is the resolution scene");
    Label labl_message = new Label("Volume settings");
    Label labl_generalvolume = new Label("General volume");
    Label labl_effectvolume = new Label("Effect volume");
    Label labl_musicvolume = new Label("Music volume");

    // Create the buttons
    Button optionsButton= new Button("Go to options");
    Button volumeButton= new Button("Go to volume settings");
    Button resolutionButton= new Button("Go to resolution settings");
    Button saveButton = new Button("save");
    Button exitButton = new Button("exit");

    // Create the sliders
    Slider slider_generalvolume;
    Slider slider_effectvolume;
    Slider slider_musicvolume;

    @Override
    public void start(Stage optionsStage) {
        // Setup the sliders
        slider_generalvolume = new Slider();
        slider_generalvolume.setMin(0);
        slider_generalvolume.setMax(100);
        slider_generalvolume.setValue(50);
        slider_generalvolume.setShowTickLabels(true);
        slider_generalvolume.setShowTickMarks(true);
        slider_generalvolume.setBlockIncrement(10);

        slider_effectvolume = new Slider();
        slider_effectvolume.setMin(0);
        slider_effectvolume.setMax(100);
        slider_effectvolume.setValue(50);
        slider_effectvolume.setShowTickLabels(true);
        slider_effectvolume.setShowTickMarks(true);
        slider_effectvolume.setBlockIncrement(10);

        slider_musicvolume = new Slider();
        slider_musicvolume.setMin(0);
        slider_musicvolume.setMax(100);
        slider_musicvolume.setValue(50);
        slider_musicvolume.setShowTickLabels(true);
        slider_musicvolume.setShowTickMarks(true);
        slider_musicvolume.setBlockIncrement(10);

        // Setup the main button
        optionsButton.setOnAction(e -> optionsStage.setScene(optionsMenu));
        volumeButton.setOnAction(e -> optionsStage.setScene(volumeMenu));
        resolutionButton.setOnAction(e -> optionsStage.setScene(resolutionMenu));
        exitButton.setOnAction(e -> Platform.exit());
        saveButton.setOnAction(e -> Platform.exit());

        // Setup the layout and add elements to it
        VBox optionsLayout = new VBox(20);
        optionsLayout.getChildren().addAll(optionslabel, volumeButton, resolutionButton, exitButton);
        optionsLayout.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
        optionsMenu = new Scene(optionsLayout, 300, 250);

        VBox volumeLayout = new VBox(20);
        volumeLayout.getChildren().addAll(volumelabel, saveButton, optionsButton);
        volumeLayout.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
        volumeMenu = new Scene(volumeLayout, 300, 250);

        VBox resolutionLayout = new VBox(20);
        resolutionLayout.getChildren().addAll(resolutionlabel, saveButton, optionsButton);
        resolutionLayout.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
        resolutionMenu = new Scene(resolutionLayout, 300, 250);

        // Setup stage and start it
        optionsStage.setTitle("Options");
        optionsStage.setScene(optionsMenu);
        optionsStage.show();
    }

    public static void main(String[] args) {
        launch(args);
        System.out.println("exited successfully!");
    }
}

Так, где эта чертова ошибка? Я не понимаю Это что-то вроде вуду Java или JavaFX, что вы не можете видеть кнопки второй сцены?

Ответы [ 2 ]

3 голосов
/ 27 апреля 2019

Проблема от saveButton и optionButton от layout.getChildren().addAll(..., saveButton, optionButton).Узлы Java FX ограничены максимум одним родителем и максимум одной сценой.Попытка использовать его в нескольких местах либо удаляет его из старого родителя, либо приводит к исключению.В вашем случае старый родитель удаляется и заменяется новым.Чтобы визуализировать проблему, вы можете изменить порядок инициализации макета, и, таким образом, вы увидите, что макет тома будет работать, но не другой.

Итак, если вы создадите уникальные экземпляры saveButtonи optionsButton для каждого макета, он будет работать.

Пример:

Button saveButtonVolume = new Button("save");
Button saveButtonResolution = new Button("save");

// ...

saveButtonVolume.setOnAction(e -> Platform.exit());
saveButtonResolution.setOnAction(e -> Platform.exit());

// ...

resolutionLayout.getChildren().addAll(resolutionlabel, saveButtonResolution, optionsButtonResolution);
volumeLayout.getChildren().addAll(volumelabel, saveButtonVolume, optionsButtonVolume);

К сожалению, я не нашел способа дублировать или клонировать узел Java FX, что упростило быпроблема (пример: saveButton.clone()).

1 голос
/ 28 апреля 2019

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

package view.options;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Options extends Application {
    // Create the labels
    Label optionslabel= new Label("This is the options scene");
    Label volumelabel= new Label("This is the volume scene");
    Label resolutionlabel= new Label("This is the resolution scene");
    Label labl_message = new Label("Volume settings");
    Label labl_generalvolume = new Label("General volume");
    Label labl_effectvolume = new Label("Effect volume");
    Label labl_musicvolume = new Label("Music volume");

    // Create the buttons
    Button optionsButton= new Button("Go to options");
    Button volumeButton= new Button("Go to volume settings");
    Button resolutionButton= new Button("Go to resolution settings");
    Button saveButton = new Button("save");
    Button exitButton = new Button("exit");

    VBox theOneAndOnlyLayout = new VBox(20);    
    Scene theOneAndOnlyScene;

    @Override
    public void start(Stage theOneAndOnlyStage) {
        theOneAndOnlyLayout.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");

        theOneAndOnlyScene = new Scene(theOneAndOnlyLayout, 300, 250);

        theOneAndOnlyLayout.getChildren().setAll(optionslabel, volumeButton, resolutionButton, exitButton);

        optionsButton.setOnAction(e -> {
            theOneAndOnlyStage.setTitle("Options");
            theOneAndOnlyLayout.getChildren().setAll(optionslabel, volumeButton, resolutionButton, exitButton);
        });
        volumeButton.setOnAction(e -> {
            theOneAndOnlyStage.setTitle("Volume");
            theOneAndOnlyLayout.getChildren().setAll(volumelabel, saveButton, optionsButton);
        });
        resolutionButton.setOnAction(e -> {
            theOneAndOnlyStage.setTitle("Resolution");
            theOneAndOnlyLayout.getChildren().setAll(resolutionlabel, saveButton, optionsButton);
        });
        exitButton.setOnAction(e -> Platform.exit());
        saveButton.setOnAction(e -> Platform.exit());

        // Setup stage and start it
        theOneAndOnlyStage.setTitle("Options");
        theOneAndOnlyStage.setScene(theOneAndOnlyScene);
        theOneAndOnlyStage.show();
    }

    public static void main(String[] args) {
        launch(args);
        System.out.println("exited successfully!");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...