1

我有一个实现Actionlistener. 单击此类中的按钮后,我希望它在我指定的精确时间,更早和其他地方执行某些操作。所以我做了这些课程:

class DoSomething implements ActionListener{
     public void actionPerformed(ActionEvent a){
     while(true){
         String test = obtainTime.time;

    if(test.matches("(.*)17:29:30(.*)")){
         Class.doSomethingMethod();
    }
        //Rest of the code
     }
     }
}

class ObtainTime{
     static DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
     static Calendar cal = Calendar.getInstance();
     static String time = dateFormat.format(cal.getTime());
}

所以问题是,我只得到点击它的时间。第二件事是按钮变得不可点击,因为它仍在运行,有没有办法让它在代码仍在后台运行时再次可点击?感谢您的任何帮助。

4

4 回答 4

1

如果您正在做一些快速的事情和/或需要您在达到目标时间时更新 UI 的事情,那么您想要使用Java Swing Timer。更多关于这方面的文档在这里:Oracle 的 Swing Timer 教程。如果您正在执行一项长期运行的任务,您将需要遵循 andersoj 的建议并使用预定的执行程序。

于 2013-03-14T18:02:14.117 回答
0

如果你想并行地做几件事,你必须使用线程。你可以通过使用Thread扩展你的类或实现Runnable 接口来做到这一点。 两种方式的不错的教程都可以在这里找到。

要获取与您的模式匹配的甲酸盐时间和日期,请查看此文档,您可以在其中找到在 java 中格式化日期和时间的模式。

于 2013-03-14T17:36:51.347 回答
0

看起来您正在使用 Swing 作为您的 GUI API。你应该使用javax.swing.SwingWorker来实现你正在寻找的东西。可以按如下方式完成:

import javax.swing.*;
import java.util.*;
import java.text.*;
import java.awt.*;

public class SWorker extends JFrame
{
    JLabel label ;
    DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    Calendar cal = Calendar.getInstance();
    static SwingWorker worker;
    public void createAndShowGUI()
    {
        setTitle("SwingWorker Demo");
        label = new JLabel();
        getContentPane().add(label,BorderLayout.NORTH);
        setSize(300,200);
        worker = new SwingWorker<String, String>() 
        {
            @Override
            public String doInBackground() 
            {
               cal = Calendar.getInstance();
               String test = dateFormat.format(cal.getTime());
               while (!(test.matches("(.*)23:41:30(.*)")) && ! isCancelled())
               {
                   publish(new String[] {test});
                    Thread.sleep(5);//Added to sleep the thread for 5 ms so that load could be shed from processor..
                   cal = Calendar.getInstance();
                   test = dateFormat.format(cal.getTime());
               }
               return test;
            }

            @Override
            public void done() //This method is called when doInBackground() finishes. i.e when pattern is matched
            {
                try
                {
                    //Call here the method that you want to call after the time matches.
                    label.setText(get() + " Time's up ...!!");  
                }
                catch (Exception ex){}

            }
            @Override
            public void process(java.util.List<String> chunks)
            {
                label.setText(chunks.get(chunks.size()-1));
            }
        };
        String time = dateFormat.format(cal.getTime());
        label.setText(time);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public void start()
    {
        worker.execute();
    }
    public static void main(String st[])
    {
        SwingUtilities.invokeLater( new Runnable()
        {
            @Override
            public void run()
            {
                SWorker sWorker = new SWorker();
                sWorker.createAndShowGUI();
                sWorker.start();
            }
        });
    }
}

要了解有关如何使用的更多信息,请查看SwingWorker 上SwingWorker的官方教程

于 2013-03-14T18:11:57.047 回答
0

您的第一个问题:虽然令人困惑,但我想您是在问为什么您只能获得第一次按下按钮时所测量的时间。答案是因为当你第一次按下按钮时,你加载了ObtainTime类。当您加载该类时,静态初始化程序运行一次且仅一次。该行:

static String time = dateFormat.format(cal.getTime());

是一个静态初始化器。你可能想要做的是更像这样的事情:

class DoSomething implements ActionListener{

  private final ScheduledExecutor scheduler = executors.newSingleThreadScheduledExecutor();
  private final long timeToRunAction;

   DoSomething(long timeToRunAction) {
     this.timeToRunAction = timeToRunAction;
   }

   public void actionPerformed(ActionEvent a)
   {
     long currentTime = System.currentTimeMillis();
     long delayTime = timeToRunAction - currentTime;
     scheduler.schedule(new Runnable() {
         public void run() { Class.doSomethingMethod(); }
     }, delayTime, TimeUnit.MILLISECONDS);
   }
}

如果你使用这个类,那么当你实例化它时,你在构造函数中指定目标时间。您可能希望它更具动态性,这很好,您只需使该timeToRunAction字段可变并提供一种设置它的方法。此处的时间以从 unix 纪元开始的毫秒数指定。如果你需要做一些日历魔术来计算你的目标时间,我已经把它省略了。

您的第二个问题:我强烈建议您不要使用自己的并发,而是使用它ScheduledExecutor.schedule()来执行此操作。您将需要使用日历来计算正确的延迟时间(可能以毫秒为单位)来安排活动。

于 2013-03-14T17:51:24.177 回答