我对被注入(inject)的存储库进行任何操作时都遇到问题。
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8413)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:748)
Caused by:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor21.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 48 more
Caused by: java.lang.NullPointerException
at pl.com.jg.serviceapp.controllers.ReportFrameController.generateButtonClicked(ReportFrameController.java:54)
... 58 more
我的ReportFrameController
(使用问题存储库):
@Controller
public class ReportFrameController{
@FXML
private Button generateButton;
@FXML
private Button cancelButton;
@FXML
private TextArea textReport;
@Autowired
@Qualifier(value = "kr")
private KeywordRepository keywordRepository;
@FXML
public void cancelButtonClicked(ActionEvent event) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/menuFrame.fxml"));
Scene scene = new Scene(root);
Stage stage = (Stage) cancelButton.getScene().getWindow();
stage.hide();
stage.setTitle("Logged");
stage.setScene(scene);
stage.show();
}
@FXML
public void generateButtonClicked(ActionEvent event) throws NullPointerException{
String word, checking;
checking = textReport.getText().toLowerCase();
for (Keyword i : keywordRepository.findAll()) { //InteliJ suggest trouble on this line
word = i.getName();
System.out.println("Word: " + word);
System.out.println("Checking: " + checking);
if (checking.contains(word)) {
System.out.println("I found the key! " + word);
} else System.out.println("I didn't found the key! " + word);
}
Stage stage = (Stage) generateButton.getScene().getWindow();
stage.close();
}
}
在另一个仓库上操作是可以的:
@Controller
public class MainFrameController {
@FXML
public Button connectButton;
@FXML
private PasswordField passwordBox;
@FXML
private TextField usernameBox;
@FXML
private Label answerLb;
@Autowired
UserController userController;
@FXML
void connectClicked(ActionEvent event) throws Exception {
String login;
String password;
String answer;
login = usernameBox.getText();
password = MD5(passwordBox.getText());
answer = userController.auth(login, password);
answerLb.setText(answer);
if (answer.equals("ok")) {
try {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/menuFrame.fxml"));
Scene scene = new Scene(root);
Stage stage = (Stage) connectButton.getScene().getWindow();
stage.hide();
stage.setTitle("Logged in as: " + login);
stage.setScene(scene);
stage.show();
} catch (IOException e) {
System.out.println("Failed to create new Window.");
}
}
}
public String MD5(String s) throws Exception{
MessageDigest m=MessageDigest.getInstance("MD5");
m.update(s.getBytes(),0,s.length());
String pass = new BigInteger(1,m.digest()).toString(16);
return(pass);
}
两个存储库都有合适的模型。数据库中的实体有一些条目。 还需要其他东西吗?
编辑。 添加主类:
@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan(basePackages = {"pl.com.jg.serviceapp.controllers",
"pl.com.jg.serviceapp.services"})
@EntityScan("pl.com.jg.serviceapp.models")
@EnableJpaRepositories(basePackages = {"pl.com.jg.serviceapp.repositories"})
public class ServiceappApplication extends Application{
private ConfigurableApplicationContext springContext;
private Parent rootNode;
public static void main(final String[] args) {
Application.launch(args);
}
@Override
public void init() throws Exception {
springContext = SpringApplication.run(ServiceappApplication.class);
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/mainFrame.fxml"));
fxmlLoader.setControllerFactory(springContext::getBean);
rootNode = fxmlLoader.load();
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(rootNode));
stage.setTitle("SERVICEAPP");
stage.show();
}
@Override
public void stop() throws Exception {
springContext.close();
}
}
编辑:
添加MenuFrameController:
@Controller
public class MenuFrameController {
@FXML
private Button generateReportButton;
@FXML
void generateReportButtonClicked(ActionEvent event) throws Exception {
try {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/reportFrame.fxml"));
Scene scene = new Scene(root);
Stage stage = (Stage) generateReportButton.getScene().getWindow();
stage.setTitle("Generate new report");
stage.setScene(scene);
stage.show();
} catch (IOException e) {
System.out.println("Failed to create Generate Window.");
}
}
}
最佳答案
加载 reportFrame.fxml
时,您没有在 FXMLLoader
上设置 Controller 工厂。因此,当 FXMLLoader
需要 ReportFrameController
的实例时,它只是直接实例化一个实例,而不是从 Spring 应用程序上下文中获取一个实例。由于 spring 不管理 Controller ,因此无法向其中注入(inject)任何内容。
只需使用与加载 mainFrame.fxml
相同的模式即可加载 reportFrame.fxml
。您可以将 ApplicationContext
本身注入(inject) Controller 中以实现此目的。请注意,这意味着您的 MenuFrameController
也必须由 spring 管理(因此在加载其相应的 FXML 文件等时使用相同的技术)。
另外,顺便说一句,您应该制作所有 Controller 原型(prototype),因为每次加载相同的 FXML 文件时,您都需要一个新的 Controller 实例。
@Controller
@Scope("prototype")
public class MenuFrameController {
@FXML
private Button generateReportButton;
@Autowired
private ApplicationContext springContext ;
@FXML
void generateReportButtonClicked(ActionEvent event) throws Exception {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/reportFrame.fxml"));
fxmlLoader.setControllerFactory(springContext::getBean);
Parent root = fxmlLoader.load();
Scene scene = new Scene(root);
Stage stage = (Stage) generateReportButton.getScene().getWindow();
stage.setTitle("Generate new report");
stage.setScene(scene);
stage.show();
} catch (IOException e) {
System.out.println("Failed to create Generate Window.");
}
}
}
<小时/>
如果您愿意,可以通过创建一个封装加载功能的类来减少重复代码,并在需要的地方注入(inject)它的实例:
public class SpringFXMLLoader {
@Autowired
private ApplicationContext springContext ;
public Parent load(String resourceName) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource(resourceName));
loader.setControllerFactory(springContext::getBean);
return loader.load();
}
}
那么你的主类就可以做到
@Override
public void init() throws Exception {
springContext = SpringApplication.run(ServiceappApplication.class);
rootNode = springContext.getBean(SpringFXMLLoader.class).load("/fxml/mainFrame.fxml");
}
你的MenuFrameController
简化(一点点)为
@Controller
@Scope("prototype")
public class MenuFrameController {
@FXML
private Button generateReportButton;
@Autowired
private SpringFXMLLoader fxmlLoader ;
@FXML
void generateReportButtonClicked(ActionEvent event) throws Exception {
try {
Parent root = fxmlLoader.load("/fxml/reportFrame.fxml");
Scene scene = new Scene(root);
Stage stage = (Stage) generateReportButton.getScene().getWindow();
stage.setTitle("Generate new report");
stage.setScene(scene);
stage.show();
} catch (IOException e) {
System.out.println("Failed to create Generate Window.");
}
}
}
关于JavaFX + Spring Boot + JPA-NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50455295/