[英]java.lang.IllegalStateException:Not on FX application when using quartz
I'm trying to use a javafx alert in a task schedule in quartz: 我试图在石英任务计划中使用javafx警报:
public class ChecarJob implements Job{
private Connection con;
public ChecarJob() {
this.con = new ConnectionFactory().getConnection();
}
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Executou!");
try {
String verStatus = "SELECT COUNT(*) FROM equipamento_requisicao";
PreparedStatement stmt = con.prepareStatement(verStatus);
ResultSet rsStatus = stmt.executeQuery();
if(rsStatus.next()){
Alerts a = new Alerts();
int Resultado = rsStatus.getInt(1);
if(Resultado>Sessao.getInstancia().getQtdRegistroBD()){
Sessao.getInstancia().setQtdRegistroBD(Resultado);
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("SUCESS");
alert.setHeaderText("SUCESS");
alert.setContentText("SUCESS");
alert.showAndWait();
}
else if(Resultado<Sessao.getInstancia().getQtdRegistroBD()){
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("FAIL");
alert.setHeaderText("FAIL");
alert.setContentText("FAIL");
alert.showAndWait();
Sessao.getInstancia().setQtdRegistroBD(Resultado);
}
else{
//aq não irei fazer nada.
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
calling in my main class: 打电话给我的主要班级:
public void start(Stage stage) throws Exception {
JobDetail j = JobBuilder.newJob(ChecarJob.class).build();
Trigger t = TriggerBuilder.newTrigger().withIdentity("CroneTrigger")
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(60).repeatForever()).build();
Scheduler s = StdSchedulerFactory.getDefaultScheduler();
s.start();
s.scheduleJob(j,t);
msg do error: 味精做错误:
java.lang.IllegalStateException: Not on FX application thread;
java.lang.IllegalStateException:不在FX应用程序线程上; currentThread = DefaultQuartzScheduler_Worker-2Executou!
currentThread = DefaultQuartzScheduler_Worker-2Executou!
JavaFX, like most UI toolkits, is single-threaded and not thread-safe. 像大多数UI工具包一样,JavaFX是单线程的并且不是线程安全的。 Once a scene graph is being displayed in a window, it must only be interacted with on the JavaFX Application Thread .
场景图一旦显示在窗口中,就只能在JavaFX Application Thread上进行交互。 And some objects must be instantiated on the FX thread.
并且某些对象必须在FX线程上实例化 。 To do otherwise can lead to errors, as you've encountered, or just full on undefined behavior .
否则,可能会导致错误(如您所遇到的那样),或者只会导致未定义的行为 。 If you're on a background thread and you need to schedule an action with the FX thread, you can use
Platform.runLater(Runnable)
(link is to the Javadoc). 如果您在后台线程上,并且需要安排FX线程的操作,则可以使用
Platform.runLater(Runnable)
(链接到Javadoc)。
Your code is not a minimal and complete example, so I can't be sure of what everything does. 您的代码不是一个最小且完整的示例,因此我不确定所有操作。 In general, however, I would start by moving all the code relating to
Alert
instances into a runLater
call. 但是,总的来说,我将从将与
Alert
实例相关的所有代码移到runLater
调用开始。
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Executou!");
try {
String verStatus = "SELECT COUNT(*) FROM equipamento_requisicao";
PreparedStatement stmt = con.prepareStatement(verStatus);
ResultSet rsStatus = stmt.executeQuery();
if (rsStatus.next()) {
Alerts a = new Alerts(); // what does this do?
int Resultado = rsStatus.getInt(1);
if (Resultado > Sessao.getInstancia().getQtdRegistroBD()) {
Sessao.getInstancia().setQtdRegistroBD(Resultado); // unknown side-effects
Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("SUCESS");
alert.setHeaderText("SUCESS");
alert.setContentText("SUCESS");
alert.showAndWait();
});
} else if (Resultado < Sessao.getInstancia().getQtdRegistroBD()) {
Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("FAIL");
alert.setHeaderText("FAIL");
alert.setContentText("FAIL");
alert.showAndWait();
});
Sessao.getInstancia().setQtdRegistroBD(Resultado); // unknown side-effects
} else {
//aq não irei fazer nada.
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Some notes: 一些注意事项:
PreparedStatement
, ResultSet
) when done with them. PreparedStatement
, ResultSet
)。 Use try-with-resources . runLater
do not wait for the Runnable
to return. runLater
的调用不等待Runnable
返回。 runLater
call on the assumption that they don't. runLater
调用之外,但前提是它们不会。 Alerts a = new Alerts()
is actually used. Alerts a = new Alerts()
位置。 Resultado
does not follow standard Java naming conventions for local variables. Resultado
不遵循本地变量的标准Java命名约定。 I am new to java and do not understand much about threads
我是Java的新手,对线程不了解
Not having at least a basic understanding of concurrency in Java will hinder your efforts to create all but the most trivial of GUI applications. 至少对Java并发没有基本的了解会阻碍您创建除最琐碎的GUI应用程序之外的所有应用程序。 I highly recommend you study this topic before moving forward.
我强烈建议您在继续之前研究此主题。 As a start , read these:
首先 ,请阅读以下内容:
Also, a good book on the topic is Java Concurrency in Practice by Brian Goetz et al. 同样,关于该主题的一本好书是Brian Goetz等人的《 Java Concurrency in Practice 》。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.