javaFX:如何定期从数据库加载信息并将其显示在标签上?
javaFX : How to periodically load information from db and show it on a Label?
我想定期执行一个方法,这个方法从数据库中获取信息并将其显示到标签中,我尝试了以下代码:
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//update information
miseAjour();
}
}, 0, 2000);
当我 运行 主程序时,后台服务 运行 也正常但是当数据库上的信息发生变化时我得到这个异常:
Exception in thread "Timer-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = Timer-0
这是方法 miseAjour 的代码:
public void miseAjour(){
try {
dbConnection db = new dbConnection();
Connection connect = db.connectiondb();
connect.setAutoCommit(false);
Statement stmt= connect.createStatement();
ResultSet rs = stmt.executeQuery("SELECT count(*) as nbrAderent FROM gss_aderent ");
int nbrAderent = rs.getInt("nbrAderent");
rs.close();
stmt.close();
connect.commit();
connect.close();
main_nbrAdrTot.setText(nbrAderent + "");
} catch (SQLException ex) {
Logger.getLogger(SimpleController.class.getName()).log(Level.SEVERE, null, ex);
}
}
你可以为此使用 Timer,但我建议使用 API 提供的 JavaFX,称为 ScheduledService。
ScheduledService 是针对 execute the same Task at regular intervals
的,因为它在内部创建了一个 Task
,所以有 API 可以帮助您将值绑定到 UI 控件。
ScheduledService<Object> service = new ScheduledService<Object>() {
protected Task<Object> createTask() {
return new Task<Object>() {
protected Object call() {
// Call the method and update the message
updateMessage(miseAjour());
return object; // Useful in case you want to return data, else null
}
};
}
};
service.setPeriod(Duration.seconds(10)); //Runs every 10 seconds
//bind the service message properties to your Label
label.textProperty().bind(service.messageProperty()); // or use your label -> main_nbrAdrTot
在 dbcall 方法中 miseAjour
,return 您已获取的值,并且您希望使用 :
更新标签
public String miseAjour(){
String nbrAderent = null;
try {
dbConnection db = new dbConnection();
Connection connect = db.connectiondb();
connect.setAutoCommit(false);
Statement stmt= connect.createStatement();
ResultSet rs = stmt.executeQuery("SELECT count(*) as nbrAderent FROM gss_aderent ");
nbrAderent = String.valueOf(rs.getInt("nbrAderent"));
connect.commit();
} catch (SQLException ex) {
Logger.getLogger(SimpleController.class.getName()).log(Level.SEVERE, null, ex);
}
finally {
rs.close();
stmt.close();
connect.close();
}
return nbrAderent;
}
最后我解决了问题,这是代码:
public class TimerServiceApp {
public void start() throws Exception {
TimerService service = new TimerService();
service.setPeriod(Duration.seconds(10));
service.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
main_nbrAdrTot.setText(t.getSource().getMessage());
}
});
service.start();
}
private class TimerService extends ScheduledService<Integer> {
private final StringProperty nbrTotAderent = new SimpleStringProperty();
public final void setTotalAderentNumber(String value ) {
nbrTotAderent.set(value);
}
public String getTotalAderentNumber() throws SQLException {
String nbrAderent = null;
ResultSet rs=null;
Statement stmt=null;
Connection connect=null;
try {
dbConnection db = new dbConnection();
connect = db.connectiondb();
connect.setAutoCommit(false);
stmt= connect.createStatement();
rs = stmt.executeQuery("SELECT count(*) as nbrAderent FROM gss_aderent ");
nbrAderent = String.valueOf(rs.getInt("nbrAderent"));
connect.commit();
} catch (SQLException ex) {
Logger.getLogger(SimpleController.class.getName()).log(Level.SEVERE, null, ex);
}
finally {
rs.close();
stmt.close();
connect.close();
}
System.out.println(" Total aderent number updated to :" + nbrAderent + " Aderents ");
return nbrAderent;
}
protected Task<Integer> createTask() {
return new Task<Integer>() {
protected Integer call() throws SQLException {
nbrTotAderent.setValue(getTotalAderentNumber());
updateMessage(getTotalAderentNumber());
return Integer.parseInt(getTotalAderentNumber());
}
};
}
}
} `
我通过以下方式调用此服务:
TimerServiceApp s = new TimerServiceApp();
s.start();
我不知道该解决方案是否经过优化但它有效 :) 谢谢@ItachiUchiha 我从您在以下
中的回答中获取了解决方案
我想定期执行一个方法,这个方法从数据库中获取信息并将其显示到标签中,我尝试了以下代码:
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//update information
miseAjour();
}
}, 0, 2000);
当我 运行 主程序时,后台服务 运行 也正常但是当数据库上的信息发生变化时我得到这个异常:
Exception in thread "Timer-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = Timer-0
这是方法 miseAjour 的代码:
public void miseAjour(){
try {
dbConnection db = new dbConnection();
Connection connect = db.connectiondb();
connect.setAutoCommit(false);
Statement stmt= connect.createStatement();
ResultSet rs = stmt.executeQuery("SELECT count(*) as nbrAderent FROM gss_aderent ");
int nbrAderent = rs.getInt("nbrAderent");
rs.close();
stmt.close();
connect.commit();
connect.close();
main_nbrAdrTot.setText(nbrAderent + "");
} catch (SQLException ex) {
Logger.getLogger(SimpleController.class.getName()).log(Level.SEVERE, null, ex);
}
}
你可以为此使用 Timer,但我建议使用 API 提供的 JavaFX,称为 ScheduledService。
ScheduledService 是针对 execute the same Task at regular intervals
的,因为它在内部创建了一个 Task
,所以有 API 可以帮助您将值绑定到 UI 控件。
ScheduledService<Object> service = new ScheduledService<Object>() {
protected Task<Object> createTask() {
return new Task<Object>() {
protected Object call() {
// Call the method and update the message
updateMessage(miseAjour());
return object; // Useful in case you want to return data, else null
}
};
}
};
service.setPeriod(Duration.seconds(10)); //Runs every 10 seconds
//bind the service message properties to your Label
label.textProperty().bind(service.messageProperty()); // or use your label -> main_nbrAdrTot
在 dbcall 方法中 miseAjour
,return 您已获取的值,并且您希望使用 :
public String miseAjour(){
String nbrAderent = null;
try {
dbConnection db = new dbConnection();
Connection connect = db.connectiondb();
connect.setAutoCommit(false);
Statement stmt= connect.createStatement();
ResultSet rs = stmt.executeQuery("SELECT count(*) as nbrAderent FROM gss_aderent ");
nbrAderent = String.valueOf(rs.getInt("nbrAderent"));
connect.commit();
} catch (SQLException ex) {
Logger.getLogger(SimpleController.class.getName()).log(Level.SEVERE, null, ex);
}
finally {
rs.close();
stmt.close();
connect.close();
}
return nbrAderent;
}
最后我解决了问题,这是代码:
public class TimerServiceApp {
public void start() throws Exception {
TimerService service = new TimerService();
service.setPeriod(Duration.seconds(10));
service.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
main_nbrAdrTot.setText(t.getSource().getMessage());
}
});
service.start();
}
private class TimerService extends ScheduledService<Integer> {
private final StringProperty nbrTotAderent = new SimpleStringProperty();
public final void setTotalAderentNumber(String value ) {
nbrTotAderent.set(value);
}
public String getTotalAderentNumber() throws SQLException {
String nbrAderent = null;
ResultSet rs=null;
Statement stmt=null;
Connection connect=null;
try {
dbConnection db = new dbConnection();
connect = db.connectiondb();
connect.setAutoCommit(false);
stmt= connect.createStatement();
rs = stmt.executeQuery("SELECT count(*) as nbrAderent FROM gss_aderent ");
nbrAderent = String.valueOf(rs.getInt("nbrAderent"));
connect.commit();
} catch (SQLException ex) {
Logger.getLogger(SimpleController.class.getName()).log(Level.SEVERE, null, ex);
}
finally {
rs.close();
stmt.close();
connect.close();
}
System.out.println(" Total aderent number updated to :" + nbrAderent + " Aderents ");
return nbrAderent;
}
protected Task<Integer> createTask() {
return new Task<Integer>() {
protected Integer call() throws SQLException {
nbrTotAderent.setValue(getTotalAderentNumber());
updateMessage(getTotalAderentNumber());
return Integer.parseInt(getTotalAderentNumber());
}
};
}
}
} `
我通过以下方式调用此服务:
TimerServiceApp s = new TimerServiceApp();
s.start();
我不知道该解决方案是否经过优化但它有效 :) 谢谢@ItachiUchiha 我从您在以下