【问题标题】:how to switching scenes in javafx (NO FXML)如何在 javafx 中切换场景(无 FXML)
【发布时间】:2019-11-09 17:02:23
【问题描述】:

请大家谅解,我是初学者;)

我正在尝试使用 JavaFX 构建一个简单的应用程序。问题是当我第一次打开窗口时它运行良好,但是如果我想改变场景它会抛出一个错误......

线程“JavaFX 应用程序线程”中的异常 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;
}
    }

我可以请您展示修复错误的正确方法吗?

【问题讨论】:

    标签: java javafx illegalargumentexception


    【解决方案1】:

    JavaFX 定义了一个场景图,它是一个具有单个根节点的树数据结构。对于您的应用程序(即您发布的代码),根节点是primaryStage(这是Main 类中方法start() 中的参数)。 primaryStage 可以有多个 Scenes。每个Scene 必须有自己的根节点。

    您收到的错误消息意味着Scene 的根不能也是另一个Scene 的根。换句话说,anchor 是 scena 类 Messages 中的根,这意味着它不能被设置为 scene 类 Login 中的根。

    除此之外,如果你想改变Scene,你需要调用Stage类的方法setScene()。这是您的 Login 类和 Messages 类,其中的更改解决了您遇到的运行时错误,并在用户单击 wejdzBtn 按钮时执行场景更改。

    登录.java
    (我只更改了方法utworzBtn()中的lambda表达式。)

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

    【讨论】:

      【解决方案2】:

      非常感谢 Abra,过去 6 小时我一直在考虑这个问题,但没有注意到这个问题。我也删除了

      public Pane messa (); 
      return anchor;
      

      我不需要它;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-09
        • 2016-09-09
        • 2016-04-13
        • 1970-01-01
        • 2020-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多