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 我从您在以下

中的回答中获取了解决方案