[英]how to switching scenes in javafx (NO FXML)
我请求您的理解,我是初学者;)
我正在尝试使用 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;
}
}
我可以请你展示修复错误的正确方法吗?
JavaFX 定义了一个场景图,它是一个具有单个根节点的树数据结构。 对于您的应用程序(即您发布的代码),根节点是primaryStage
(这是Main
类中方法start()
中的参数)。 primaryStage
可以有多个Scene
。 每个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;
}
}
消息.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;
}
}
非常感谢 Abra,过去 6 个小时我一直在考虑这个问题,但没有注意到这个问题。 我也删除了
public Pane messa ();
return anchor;
我不需要它 ;)
但是现在还有另一个问题,为什么我看不到AnchorPane上的控件?
public class Messages {
private AnchorPane anchor;
private Scene scena;
//private Label nick;
private Button sendBtn;
private TextArea poleDoWyswietlania, pobierzNick,poleDoWpisywania;
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);
sendBtn.prefHeight(30);
sendBtn.prefWidth(80);
AnchorPane.setLeftAnchor(sendBtn, 600.0);
AnchorPane.setRightAnchor(sendBtn,15.0);
AnchorPane.setBottomAnchor(sendBtn, 65.0);
}
private void pobierzNick(){
pobierzNick = new TextArea();
pobierzNick.prefHeight(570);
pobierzNick.prefWidth(120);
AnchorPane.setLeftAnchor(pobierzNick, 15.0);
AnchorPane.setBottomAnchor(pobierzNick, 15.0);
AnchorPane.setTopAnchor(pobierzNick, 15.0);
pobierzNick.setEditable(false);
pobierzNick.setWrapText(true);
}
private void poleDoWpisywania() {
poleDoWpisywania = new TextArea();
poleDoWpisywania.prefHeight(45);
poleDoWpisywania.prefWidth(435);
AnchorPane.setLeftAnchor(poleDoWpisywania, 150.0);
AnchorPane.setBottomAnchor(poleDoWpisywania, 60.0);
AnchorPane.setRightAnchor(poleDoWpisywania, 110.0);
poleDoWpisywania.setPromptText("Maksymalnie 300 znak\u00f3w");
poleDoWpisywania.setFocusTraversable(false);
final int maxLength = 300;
final int minLength = 1;
poleDoWpisywania.setOnKeyTyped(t -> {
if (poleDoWpisywania.getText().length() > maxLength)
{
int pos = poleDoWpisywania.getCaretPosition();
poleDoWpisywania.setText(poleDoWpisywania.getText(0, maxLength));
poleDoWpisywania.positionCaret(pos);
}
else if (poleDoWpisywania.getText().length() == minLength)
{
sendBtn.setDisable(false);
}
else if (poleDoWpisywania.getText().length() < minLength)
{
sendBtn.setDisable(true);
}
});
poleDoWpisywania.setWrapText(true);
}
private void poleDoWyswietlania() {
poleDoWyswietlania = new TextArea();
poleDoWyswietlania.prefHeight(435);
poleDoWyswietlania.prefWidth(535);
AnchorPane.setLeftAnchor(poleDoWyswietlania, 150.0);
AnchorPane.setTopAnchor(poleDoWyswietlania, 15.0);
AnchorPane.setRightAnchor(poleDoWyswietlania, 15.0);
poleDoWyswietlania.setEditable(false);
poleDoWyswietlania.setWrapText(true);
}
public Scene getScena() {
return scena;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.