我是JavaFX的新手,我想创建一个视图类,当按钮按下触发事件时,该视图类将调用Controller中的方法。我的代码如下:
package spacetrader.menu;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import spacetrader.Window;
public class MenuView implements Initializable {
public Window window;
public MenuCtrl menuCtrl;
@FXML
Button start;
@FXML
Pane background;
@FXML
Button exit;
public MenuView() {};
public MenuView(Window aWindow, MenuCtrl aMenuCtrl) {
window = aWindow;
menuCtrl = aMenuCtrl;
}
void renderMainMenu() {
try {
window.loadFXML(new FXMLLoader((getClass().getResource("MainMenu.fxml"))));
} catch (IOException ex) {
Logger.getLogger(MenuView.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void initialize(URL url, ResourceBundle rb) {
start.setOnAction((ActionEvent event) -> menuCtrl.newGame());
exit.setOnAction((ActionEvent event) -> menuCtrl.closeApplication());
}
}
这个编译,但是当我运行它并按下按钮时,我在lambda表达式上得到一个空指针异常。例外是指“menuCtrl”。我该如何设置我的程序来调用menuCtrl.newGame()按钮?
以下是我已经尝试过的内容:
答案 0 :(得分:1)
您的设置不常见,因为您的控制器类(您称之为MenuView
)是调用(间接地,通过您的Window
类)FXMLLoader' s的类加载方法。 FXMLLoader
解析FXML,查看fx:controller
属性,然后使用默认(无参数)构造函数对其进行实例化。 (我在这里假设您不能在setController
中的setControllerFactory
上致电FXMLLoader
或Window.loadFXML
。)因此,您有两个控制器实例:一个它创建了加载器(从不调用initialize()方法,并且永远不会注入@FXML
- 带注释的字段),以及由FXMLLoader
创建的加载器(称为无参数构造函数) ,因此未为该实例初始化window
和menuCtrl
字段。)
你应该重构这个,以便创建FXMLLoader并传递给Window类以便在其他地方加载(即不实例化控制器),或者你应该在FXMLLoader上明确设置控制器。您可以通过两个步骤实现后者:
fx:controller
属性
renderMainMenu
方法中创建的实例:-
FXMLLoader loader = new FXMLLoader((getClass().getResource("MainMenu.fxml"))) ;
loader.setController(this);
window.loadFXML(loader);
答案 1 :(得分:0)
您可以尝试使用拖放功能的Scene Builder
,您可以在几秒钟内设计一个屏幕。在代码部分中,您只需声明方法名称并在代码处理程序类中实现该方法。
您可以从here
获取答案 2 :(得分:0)
你有两个构造函数。我的猜测是你在某处加载一个FXML,它将使用no-args构造函数实例化你的控制器。在这种情况下,menuCtrl未初始化。
如果您在FXML中实例化menuCtrl,则在该字段中添加@FXML注释。