如何在特定日期/时间执行方法?

时间:2016-01-27 17:11:28

标签: java

现在我有一个方法(正确)更新GUI上的标签,从表单文本框中的用户输入倒计时:

   private void bendStopCounter() throws AWTException {

       Thread counter = new Thread() {
           public void run() {
           // timeAway is the user input int in miliseconds, hence the conversion
               for (int i=(int)(timeAway/1000); i>0; i=i-1) {
                   updateGUI(i,lblBendingStopTimer);
                   try {Thread.sleep(1000);} catch(InterruptedException e) {};
               }
           }

                 public void updateGUI(final int i, final Label lblBendingTimer) {
                       Display.getDefault().asyncExec(new Runnable() {

                           public void run() {
                              lblBendingTimer.setText("Time until bending stops: " + i/60 + " minutes and " + i%60 + " seconds.");
                           }
                       });
                 }
       };
       counter.start();
   }

这是我GUI上的监听器按钮逻辑。它从表单中解析日期/时间,并且(正确地)从BendingController类执行逻辑来执行某些操作:

   private void addBendingListener()
   {
          executeBendingButton.addSelectionListener(new SelectionAdapter() {
                 @Override
                 public void widgetSelected(SelectionEvent e) {
                       System.out.println("Bending has started! lolool");
                       //grabs UI values and pass them to controller
                       int day = dateTimeDMY.getDay();
                       int month = dateTimeDMY.getMonth();
                       int year = dateTimeDMY.getYear();
                       int hour = dateTimeHMS.getHours();
                       int minute = dateTimeHMS.getMinutes();
                       int second = dateTimeHMS.getSeconds();
                       Date date = parseDate(day, month, year, hour, minute, second);

                       try {
                              System.out.println("Waiting for " + date + " to happen...");

                              timeAway = Long.parseLong(timeAwayInMinutes.getText());
                              timeAway = TimeUnit.MINUTES.toMillis(timeAway);

                              timer.schedule(new BenderController(timeAway,cursorMoveIncrement), date);

                              timeAway = TimeUnit.MILLISECONDS.toMillis(timeAway);

                              bendStopCounter();
                       }
                       catch (Exception exc) {
                              MessageDialog.openError(shell, "Error", "Hey, jerkwad, you see those 2 friggin' textboxs?  Yeah, put valid numbers in them next time, asshole!");
                              return;
                       }                          
                 }

          });
   }

我的错误是如果用户在将来的任何时间选择开始日期/时间,计数器会在按下执行按钮后立即开始倒计时。 BenderController类逻辑将在特定时间执行,因为它正在扩展TimerTask并使用schedule()方法,如上所示。我希望bendStopCounter()方法使用与此类似的东西,并在所选日期/时间的同时开始执行。

思想?

2 个答案:

答案 0 :(得分:1)

您可以使用像Quartz这样的库来执行此操作。它非常易于使用,您可以使用Cron语法,这非常容易找到信息,因此您可以制定具体的时间表。

https://quartz-scheduler.org/

答案 1 :(得分:1)

对于短时间内的事情,例如几分钟甚至几小时,在重启程序时都没有问题(例如,意外断电),你可以使用java执行器。(SheduledExecutor

因为您似乎需要能够提前几天/几个月/几年安排 和威廉姆斯回答提到的石英一样。它具有内置的作业存储空间来保持设置作业。

然而,执行者的一些示例代码:

public class ExecTest 
{
    public static void main(String[] args)
    {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); //create an executor with 1 worker thread.
        final ScheduledFuture future = 
                executor.scheduleAtFixedRate(new TimeCounter(System.out), 0, 1000, TimeUnit.MILLISECONDS); //execute Timecounter every 1k milliseconds

        executor.schedule(
                new Runnable()
                {
                    ScheduledFuture fut= future;   //grabbing the final future

                    public void run() {
                        fut.cancel(false);          //cancel the endless counter using its future           
                    }
                }
                , 6000, TimeUnit.MILLISECONDS);     //shedule it once in 6 seks
    }
}   

public class TimeCounter implements Runnable
{
    private PrintStream display;
    private long startTime;

    public TimeCounter(PrintStream out)
    {
        startTime=System.currentTimeMillis();
        display= out;
    }

    public void run() 
    {
        updateGUI((System.currentTimeMillis()-startTime)/1000);

    }

    private void updateGUI(final long i) 
    {
        display.println("Time until bending stops: " + i/60 + " minutes and " + i%60 + " seconds.");
    }
}