为什么Java在第二个场景中不显示按钮

时间:2019-04-27 18:32:45

标签: java javafx

我的程序中有三个场景。 当我启动它时,我看到带有所有按钮的第一个场景。 然后,当我转到第二个场景时,我只会看到标签,按钮没有显示出来。 在第三个场景中,一切正常,我看到了标签和按钮。

问题是,为什么我的按钮没有出现在第二个场景中?

我试图切换按钮和场景的设置顺序,以使场景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 个答案:

答案 0 :(得分:3)

问题出在saveButton,而optionButtonlayout.getChildren().addAll(..., saveButton, optionButton)。 Java FX节点最多只能有1个父级和最多1个场景。尝试在多个位置使用它会从旧的父项中删除它,或者导致异常。在您的情况下,旧的父级将被删除并由新的父级替换。为了显示该问题,您可以更改布局初始化的顺序,因此,您将看到卷布局可以正常工作,而另一个不能正常工作。

因此,如果您为每个布局创建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 :(得分:1)

因此,这是一个仅包含一个场景,舞台和布局的工作示例。 所有按钮都可以那样重复使用。这通常不是我通常喜欢的方式,但是它可以使代码更短。

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!");
    }
}