java fx 多个窗口,用JavaFX打开多个窗口

I'm trying to open multiple windows with JavaFX, I have an eventlistener that opens a new window when a button is clicked it looks like this:

@FXML

private void joinAction() {

Parent root;

try {

Stage stage = (Stage) joinButton.getScene().getWindow();

stage.close();

root = FXMLLoader.load(getClass().getResource("main.fxml"));

stage = new Stage();

stage.setTitle("TuneUs");

stage.setScene(new Scene(root));

stage.show();

} catch (IOException e) {e.printStackTrace();}

}

the first window opens and the new one opens, but my problem is getting events to work with my second window

in main.fxml I have this line:

Then in my controller class I have this method:

@FXML

private void sendChat() {

System.out.println("test");

}

but Intellij is telling me that; no controller specified for top level element

So, my question is: Do I need to create multiple controller classes or can I use just one for multiple windows if so how?

解决方案

The recommended approach is to define a controller for each FXML. Since controllers are very lightweight this shouldn't add much overhead. The controller for your main.fxml file might be as simple as

import javafx.fxml.FXML ;

public class MainController {

@FXML

private void sendChat() {

// ...

}

}

I have used this approach with fairly large numbers of FXML files and corresponding controllers in a single project, and have had no issues with managing the code etc. I recommend using a naming convention of the form Main.fxml MainController.

If your controllers need to share data, use the techniques outlined in Passing Parameters JavaFX FXML

As @Vertex points out in the comments, there is an alternative approach provided by the FXMLLoader.setController(...) method. So in your example above, you could do

@FXML

private void joinAction() {

Parent root;

try {

Stage stage = (Stage) joinButton.getScene().getWindow();

stage.close();

FXMLLoader loader = new FXMLLoader (getClass().getResource("main.fxml"));

loader.setController(this);

root = loader.load();

stage = new Stage();

stage.setTitle("TuneUs");

stage.setScene(new Scene(root));

stage.show();

} catch (IOException e) {e.printStackTrace();}

}

@FXML

private void sendChat() {

// ...

}

This approach is fine if you are not setting any fields (controls) via FXML injection (i.e. with an fx:id attribute in the fxml and a corresponding @FXML annotation in the controller). If you are, it will be very difficult to keep track of when those fields have been set. Moreover, if your joinAction handler is invoked multiple times, you will have multiple instances of the node created by main.fxml, but all sharing a single controller instance (and consequently overwriting the same injected fields). Also note that with this approach, your initialize() method will be invoked both when the original fxml file is loaded, and when the main.fxml file is loaded, which will almost certainly cause undesired effects.

One last note: if you have many FXML files, and corresponding controllers, you might want to look at the afterburner.fx framework. This is a very lightweight framework that mandates a naming convention on FXML files and their corresponding controllers, and also provides a (very) easy mechanism for sharing data between them.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值