我有一个使用 Springboot 和 Javafx 的个人程序。我一直在尝试获得更多创建 springboot 和 javafx 应用程序的技能。程序启动一个 fxml 页面,人们可以在其中更新个人...
我有一个使用 Springboot 和 Javafx 的个人程序。我一直在尝试获得更多创建 springboot 和 javafx 应用程序的技能。程序启动一个 fxml 页面,人们可以在其中更新某人的记录,单击“保存”,然后将其保存到 mssql 数据库中。
我正在尝试将新的人员记录保存到 mssql 数据库。
人员实体.java
@Entity
@Getter
@NoArgsConstructor(force = true)
@Data
@Table(name = "persons")
public class PersonEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "personID", nullable = false)
private final Integer personID;
@Column(name = "first_name")
@Setter
private String firstName;
@Column(name = "last_name")
@Setter
private String lastName;
@Column(name = "dob")
@Setter
private String dob;
PersonRepo.java
@Repository
public interface PersonRepo extends JpaRepository<PersonEntity, String> {
List<PersonEntity> findAll();
}
PersonService.java
public interface PersonService{
Optional<PersonEntity> save(PersonEntity personEntity);
PersonEntity update(PersonEntity personEntity);
PersonEntity findAll();
}
PersonServiceImpl.java
@Service
@RequiredArgsConstructor
public class PersonServiceImplimplements PersonService {
@Autowired
private PersonRepo repo;
@Override
public Optional<PersonEntity> save(PersonEntity personEntity) {
return Optional.of(repo.save(personEntity));
}
@Override
public PersonEntity update(PersonEntity personEntity){ return repo.save(personEntity);}
@Override
public PersonEntity findAll() {
return (PersonEntity ) repo.findAll();
}
}
PersonController.java
@Component
public class PersonController {
@Autowired
PersonService personService;
public TextField lName;
public TextField fName;
public TextField dob;
public Button onSaveNewPerson;
@FXML
public void onSaveNewPerson(ActionEvent event) throws SQLException {
if(fName != null){
PersonEntity newPerson = new PersonEntity ();
fName.setText(newPerson.getFirstName());
personService.save(newPerson);
}
}
人员记录.fxml
<AnchorPane fx:id="scenePane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.controllers.PersonController">
<Pane layoutX="-2.0" layoutY="91.0" prefHeight="800.0" prefWidth="1004.0">
<Label layoutX="14.0" layoutY="14.0" text="New Person Form">
<font>
<Font size="20.0"/>
</font>
</Label>
<Label layoutX="14.0" layoutY="69.0" text="First Name"/>
<Label layoutX="16.0" layoutY="130.0" text="Last name"/>
<Label layoutX="18.0" layoutY="130.0" text="Date of Birth"/>
<Label layoutX="20.0" layoutY="130.0" text="Address"/>
<TextField fx:id="fName" layoutX="98.0" layoutY="66.0"/>
<TextField fx:id="lName" layoutX="98.0" layoutY="126.0"/>
<TextField fx:id="dob" layoutX="98.0" layoutY="146.0"/>
<TextField fx:id="personAddress" layoutX="98.0" layoutY="166.0"/>
<Button fx:id="saveNewPerson" layoutX="803.0" layoutY="333.0" mnemonicParsing="false"
onAction="#onSaveNewPerson" prefHeight="58.0" prefWidth="187.0" text="Save New Person"/>
<Label layoutX="597.0" layoutY="70.0" text="DOB"/>
<TextField fx:id="dob" layoutX="691.0" layoutY="66.0"/>
</Pane>
</AnchorPane>
目前,单击 onSaveNewPersonbutton 后,我收到以下错误 -
无法调用 \'com.example.services.PersonService.save(com.example.entity.persons.PersonEntity)\',因为 \'this.personService\' 为空
我确实希望保存所有文本字段,但目前我只是使用 fname 字段进行测试。
我已确保在控制器中为 personService 设置了 @Autowired。我还确保为 PersonRepo 设置了 @Repository。
我还将 CommandLineRunner 实现添加到 FxApplication 文件中,并将测试人员添加到数据库中以确保正确连接。运行正常,人员输入成功。调查代码 -
@SpringBootApplication
@EnableJpaRepositories("com.example.repo")
public class FxApplication extends Application implements CommandLineRunner {
private ConfigurableApplicationContext springContext;
private Parent root;
@Autowired
PersonRepo personRepo;
public static void main(String[] args){
launch(FxApplication.class, args);
}
@Override
public void start(Stage stage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setControllerFactory(springContext::getBean);
fxmlLoader.setLocation(getClass().getResource("/PersonsRecord.fxml"));
Parent root = fxmlLoader.load();
stage.setTitle("Add NewPerson");
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
@Override
public void init() throws Exception{
springContext = SpringApplication.run(FxApplication.class);
}
@Override
public void stop() throws Exception{
springContext.close();
Platform.exit();
}
@Override
public void run(String... args) throws Exception {
PersonEntity person = new PersonEntity ();
person.setFirstName("TestSpring3");
person.setLastName("LastNameTest4");
person.setDOB("1/1/2000")
personRepo.save(person);
}
}
我编辑了我的代码并使用了@David Weber 提供的模板。
这是我已经编辑的 FxApplicationLauncher.java 类。
package com.example;
import javafx.application.Application;
import javafx.application.HostServices;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.*;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.stereotype.Component;
import java.io.IOException;
@SpringBootApplication
@EnableJpaRepositories("com.example.repo")
public class FxApplicationLauncher {
public static void main(String[] args) {
Application.launch(FxApplication.class, args);
}
public static class FxApplication extends Application {
private ConfigurableApplicationContext context;
@Override
public void init(){
ApplicationContextInitializer<GenericApplicationContext> initializer = applicationContext -> {
applicationContext.registerBean(Application.class, () -> FxApplication.this);
applicationContext.registerBean(Parameters.class, this::getParameters);
applicationContext.registerBean(HostServices.class, this::getHostServices);
};
this.context = new SpringApplicationBuilder()
.sources(FxApplicationLauncher.class)
.initializers(initializer)
.run(getParameters().getRaw().toArray(new String[0]));
}
@Override
public void start(Stage stage) { this.context.publishEvent(new StageIsReadyEvent(stage)); }
@Override
public void stop() throws Exception {
context.close();
Platform.exit();
System.exit(0);
}
@Component
public static class FxApplicationStageIsReadyListener implements ApplicationListener<StageIsReadyEvent>{
@Value("${spring.application.name}")
private String applicationTitle;
private ApplicationContext applicationContext;
public void JfxSpringBootStageIsReadyListener(
@Value("${spring.application.name}") String applicationTitle,
ApplicationContext applicationContext) {
this.applicationTitle = applicationTitle;
this.applicationContext = applicationContext;
}
@Override
public void onApplicationEvent(StageIsReadyEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/PersonsRecord.fxml"));
fxmlLoader.setControllerFactory(applicationContext::getBean);
Parent root = fxmlLoader.load();
Scene scene = new Scene(root, 600, 600);
Stage stage = event.getStage();
stage.setScene(scene);
stage.setTitle(this.applicationTitle);
stage.show();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public static class StageIsReadyEvent extends ApplicationEvent {
public Stage getStage() {
return (Stage) getSource();
}
public StageIsReadyEvent(Stage source) {
super(source);
}
}
}
}
由于某种原因,applicationContext 为空。
java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:208)
at com.example.gaitlabapp.FxApplicationLauncher$FxApplication$FxApplicationStageIsReadyListener.onApplicationEvent(FxApplicationLauncher.java:84)
at com.example.gaitlabapp.FxApplicationLauncher$FxApplication$FxApplicationStageIsReadyListener.onApplicationEvent(FxApplicationLauncher.java:65)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:451)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:384)
at com.example.gaitlabapp.FxApplicationLauncher$FxApplication.start(FxApplicationLauncher.java:51)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:842)