как переключать сцены в javafx (без FXML) - PullRequest
0 голосов
/ 09 ноября 2019

Прошу вашего понимания, я новичок;)

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

Исключение в потоке "JavaFX Application Thread" Java. lang.IllegalArgumentException: AnchorPane @ 1809546 [styleClass = root] уже установлен как корень другой сцены #

Основной класс


public class Main extends Application{

    //private Stage primaryStage;

    @Override
public void start(Stage primaryStage) {

    Login login = new Login();
    Scene scene = login.okno();



    primaryStage.setTitle("Komunikator sieciowy JAVA");
    primaryStage.setScene(scene);
    primaryStage.setResizable(false);
    primaryStage.show();

}

    //public Stage getPrimaryStage() {
    //  return this.primaryStage;
    //}

public static void main(String[] args) {
    launch(args);
}
}

Логин

public class Login {
    private GridPane grid;
    private Scene scene;
    private Text title;
    private Label nick;
    private Button wejdzBtn;
    private TextField userName;
    //private Alert oknoDlg;




    public Login()  {
        grid = new GridPane();
        grid.setAlignment (Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(25,25,25,25));
        scene = new Scene (grid, 300, 150);
        utworzBtn();
        utworzLogin();
        utworzTekst();
        utworzNick();
        //oknoDialogowe();


    }

    //private void oknoDialogowe()  {
        //Alert oknoDlg = new Alert(Alert.AlertType.CONFIRMATION);
        //oknoDlg.setTitle("Informacja");
        //oknoDlg.setContentText("test");  
    //  oknoDlg.setHeaderText(null);
        //oknoDlg.showAndWait();


    //}

    private void utworzBtn() {
        wejdzBtn = new Button("Zaloguj si\u0119");
        HBox hbBtn = new HBox(10);
        hbBtn.setAlignment (Pos.BOTTOM_RIGHT);
        hbBtn.getChildren().add(wejdzBtn);
        grid.add(hbBtn, 1, 2);
        //wejdzBtn.setDisable(true);
        wejdzBtn.setOnAction(e -> {
            Messages mess = new Messages();
            grid.getScene().setRoot(mess.messa());;
        });

    }

    private void utworzLogin() {

        nick = new Label("Nick:");
        grid.add(nick, 0, 1);
    }

    private void utworzNick() {
        userName = new TextField();
        grid.add(userName,1,1);
        // informacja w polu tekstowym
        userName.setPromptText("Max 15 znak\u00f3w");
        userName.setFocusTraversable(false);

        //maksymalna ilość znaków
        final int maxLength = 15;
        userName.setOnKeyTyped(t -> {
            if (userName.getText().length() > maxLength)
            {
                int pos = userName.getCaretPosition();
                userName.setText(userName.getText(0, maxLength));
                userName.positionCaret(pos);
            }
        });

    }

    private void utworzTekst() {
        title = new Text ("Dzień dobry!");
        title.setFont(Font.font("Calibri", FontWeight.NORMAL, 20));
        grid.add(title, 0, 0, 2, 1);
    }

    public Scene okno() {
        return scene;
    }


}


и немного другой класс, который я пытаюсь изменить с помощью кнопки из login.java

    public class Messages {
    private AnchorPane anchor;
    private Scene scena;
    //private Label nick;
    private Button sendBtn;
    private TextField poleDoWpisywania;
    private TextArea poleDoWyswietlania, pobierzNick;


    public Messages() {

        anchor = new AnchorPane();
        scena = new Scene(anchor, 700, 600);
        pobierzNick();
        poleDoWpisywania();
        poleDoWyswietlania();
        utworzPrzycisk();

}
    private void utworzPrzycisk() {
        sendBtn = new Button("Wy\u015Blij");
        sendBtn.setDisable(true);

    }

    private void pobierzNick(){
        pobierzNick = new TextArea();
        pobierzNick.setEditable(false);
        pobierzNick.setWrapText(true);
}

    private void poleDoWpisywania() {
    poleDoWpisywania = new TextField();


}

    private void poleDoWyswietlania() {
        poleDoWyswietlania = new TextArea();
        poleDoWyswietlania.setEditable(false);
        poleDoWyswietlania.setWrapText(true);


}


    public Pane messa() {
        return anchor;
}
    }

Могу ли я попросить вас показать правильный способ исправить ошибку?

Ответы [ 2 ]

1 голос
/ 09 ноября 2019

JavaFX определяет граф сцены, который представляет собой древовидную структуру данных с единственным корневым узлом. Для вашего приложения (т. Е. Кода, который вы разместили) корневым узлом является primaryStage (это параметр в методе start() в классе Main). primaryStage может иметь несколько Scene с. Каждый Scene должен иметь свой собственный корневой узел.

Полученное сообщение об ошибке означает, что корень Scene также не может быть корнем другого Scene. Другими словами, anchor является корнем для scena в классе Messages, что означает, что его нельзя установить в качестве корня для scene в классе Login.

Кроме того, еслиВы хотите изменить Scene, вам нужно вызвать метод setScene() класса Stage. Вот ваш класс Login и класс Messages с изменениями, которые устраняют полученную ошибку времени выполнения и выполняют смену сцены, когда пользователь нажимает кнопку wejdzBtn.

Login.java
(Я только изменил лямбда-выражение в методе utworzBtn().)

public class Login {
    private GridPane grid;
    private Scene scene;
    private Text title;
    private Label nick;
    private Button wejdzBtn;
    private TextField userName;

    public Login()  {
        grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(25,25,25,25));
        scene = new Scene(grid, 300, 150);
        utworzBtn();
        utworzLogin();
        utworzTekst();
        utworzNick();
    }

    private void utworzBtn() {
        wejdzBtn = new Button("Zaloguj si\u0119");
        HBox hbBtn = new HBox(10);
        hbBtn.setAlignment (Pos.BOTTOM_RIGHT);
        hbBtn.getChildren().add(wejdzBtn);
        grid.add(hbBtn, 1, 2);
        wejdzBtn.setOnAction(e -> {
            Messages mess = new Messages();
            Window w = scene.getWindow();
            if (w instanceof Stage) {
                Stage s = (Stage) w;
                s.setScene(mess.getScena());
            }
        });
    }

    private void utworzLogin() {
        nick = new Label("Nick:");
        grid.add(nick, 0, 1);
    }

    private void utworzNick() {
        userName = new TextField();
        grid.add(userName,1,1);
        userName.setPromptText("Max 15 znak\u00f3w");
        userName.setFocusTraversable(false);

        final int maxLength = 15;
        userName.setOnKeyTyped(t -> {
            if (userName.getText().length() > maxLength)
            {
                int pos = userName.getCaretPosition();
                userName.setText(userName.getText(0, maxLength));
                userName.positionCaret(pos);
            }
        });
    }

    private void utworzTekst() {
        title = new Text ("Dzień dobry!");
        title.setFont(Font.font("Calibri", FontWeight.NORMAL, 20));
        grid.add(title, 0, 0, 2, 1);
    }

    public Scene okno() {
        return scene;
    }
}

Messages.java
(я добавил метод getScena().)

public class Messages {
    private AnchorPane anchor;
    private Scene scena;
    private Button sendBtn;
    private TextField poleDoWpisywania;
    private TextArea poleDoWyswietlania, pobierzNick;

    public Messages() {
        anchor = new AnchorPane();
        scena = new Scene(anchor, 700, 600);
        pobierzNick();
        poleDoWpisywania();
        poleDoWyswietlania();
        utworzPrzycisk();
    }

    private void utworzPrzycisk() {
        sendBtn = new Button("Wy\u015Blij");
        sendBtn.setDisable(true);
    }

    private void pobierzNick() {
        pobierzNick = new TextArea();
        pobierzNick.setEditable(false);
        pobierzNick.setWrapText(true);
    }

    private void poleDoWpisywania() {
        poleDoWpisywania = new TextField();
    }

    private void poleDoWyswietlania() {
        poleDoWyswietlania = new TextArea();
        poleDoWyswietlania.setEditable(false);
        poleDoWyswietlania.setWrapText(true);
    }

    public Scene getScena() {
        return scena;
    }

    public Pane messa() {
        return anchor;
    }
}
0 голосов
/ 09 ноября 2019

Большое спасибо, Абра, я думал об этом последние 6 часов и не заметил этой проблемы. Я также удалил

public Pane messa (); 
return anchor;

Мне это не нужно;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...