2013-03-14 90 views
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()); 
} 

所以問題是,我只有從點擊它的時間。第二件事是按鈕變得不可點擊,因爲它仍在運行,有沒有辦法在代碼仍然在後臺運行時再次點擊?感謝您的任何幫助。

+2

你需要使用線程使用SwingWorker樣子:它可以如下完成。 – SLaks 2013-03-14 17:31:06

+0

你從來沒有設置這些靜態字段 – SLaks 2013-03-14 17:58:42

回答

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()來做到這一點,而不是滾動自己的併發。您需要使用日曆計算正確的延遲時間(可能以毫秒爲單位)以計劃活動。

0

如果你想paralely做幾件事情,你必須用Thread延長你的類或者實現Runnable interface 尼斯教程兩種方式使用線程。你可以做到這一點,可以發現here

要獲取時間&日期,甲酸,將符合您的模式,檢查this document,在那裏你可以找到的模式在Java foramtting日期&時間。

+0

日期和時間的格式不是問題。問題是我只得到點擊按鈕時的時間,所以如果我說讓它告訴我while循環內每秒鐘的時間,它會每次都打印相同的時間。 – 2013-03-14 17:54:09

+0

您是否可以更新您的問題以更清楚地瞭解「正常工作」的外觀?我認爲你提出了兩個問題,一個是關於「我只有點擊它的時間」,我不知道如何解釋;還有一個關於@Dworza和我回答的併發問題。 – andersoj 2013-03-14 17:57:40

+1

是啊..它的困惑... – Dworza 2013-03-14 17:59:58

1

如果您正在做一些快速和/或需要您在達到目標時間時更新UI的事情,則需要使用Java Swing Timer。關於此的更多文檔在這裏:Oracle's Swing Timer tutorial。如果您正在執行長時間運行的任務,那麼您需要遵循andersoj的建議並使用預定的執行程序。

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(); 
      } 
     }); 
    } 
} 

要了解更多有關如何在這個官方tutorial on SwingWorker

+0

你真的不想運行'while!test.matches()'循環,它只會在處理器中咀嚼而沒有任何理由。 – andersoj 2013-03-14 18:15:59

+0

@andersoj是的它會..但是如果用戶在選擇時間像'(。*)23:42:(。*)'時給了一些靈活性,那麼我們可以在doInBackground內愉快地使用Thread.sleep() ()',那肯定會減輕處理器的負擔。 – 2013-03-14 18:23:22

+0

是的,你可以,但JDK提供了更好更安全,更高效的原語。請參閱'Timer'或'ScheduledExecutor'。如果你想要「馬虎」匹配的時間,你可以指定你最喜歡的時間爲定時器或執行者。 – andersoj 2013-03-14 18:26:21