2014-12-03 129 views
2

我有一個簡單的GUI,可以保存並從.doc文件中獲取一些數據。Java:定時器(等待x秒)

當我按下保存按鈕,我有一個標籤,通過label.setText()說「Succes」或「錯誤」;

更新:該代碼是指在FXMLDocumentController(內置PåSceneBuilder)要跑到

我想要的標籤回去〜3秒後是空的(「」)..

我有嘗試:

try { 
    Thread.sleep(1000);    
    } 
catch(InterruptedException ex) { 
Thread.currentThread().interrupt(); 

}

,但它像,即睡眠功能凍結整個GUI所以當它睡覺,我不能與它進行交互。我如何設置一個不影響可用性的計時器? :)

回答

3

創建一個3秒後啓動的TimerTask。 這TimerTask的具有執行其通過Platform.runLater使用GUI組件的代碼(新的Runnable())

Timer timer = new Timer(); 
timer.schedule(new TimerTask() { 

     @Override 
     public void run() { 
      Platform.runLater(new Runnable() { 
       @Override 
       public void run() { 
        label.setText(""); 
       } 
      }); 

     } 
    }, 3000); 
+0

我沒有得到這個編譯錯誤,但後續運行時錯誤:線程「定時器0」中的異常java.lang.IllegalStateException:不在FX應用程序線程; currentThread = Timer-0 – 2014-12-03 21:31:21

+0

哦。如果您使用的是javafx,則必須使用Platform.runLater()處理此問題才能在gui線程中運行您的代碼。我更新了我的文章 – Deton 2014-12-03 22:06:23

+0

感謝您的時間:)我現在得到這個編譯錯誤:錯誤:找不到符號 Platform.runLater(new Runnable(){ symbol:variable Platform – 2014-12-03 22:08:33

0

您不能與GUI進行交互,因爲代碼在負責處理GUI事件並因此被阻止的事件分派線程中休眠。改爲使用此Swing Timer

給出的例子很簡單。我包括評論。

int delay = 1000; //milliseconds 

    //Create action listener which listens for the event generated by the timer 
    ActionListener taskPerformer = new ActionListener() { 
     public void actionPerformed(ActionEvent evt) { 
      Place here code to execute when the time runs out. 
     } 
    }; 
    //Simply create a timer with the created listener and start it. 
    new Timer(delay, taskPerformer).start(); 
+0

我沒有那麼在java中(尚未:d)經歷過,所以你可以給我的代碼示例等待3秒鐘,然後執行label.setText(「」); ? – 2014-12-03 21:22:11

0

請勿使用Thread.sleep()。實例化一個javax.swing.Timer並讓它做一個事件回調。如果你想保持它的方法相同,請撥打wait(),然後讓事件處理程序調用notify(),這將恢復程序。但是,你可能不需要那樣做;你可以直接使用事件處理程序刪除文本。

0

要做到這一點,你將不得不使用threading。如果您正在使用Swing,則可以使用Swing Timer。代碼看起來像這樣。把這段代碼放在你'保存'文件的地方。

int delay = 3000; 
    ActionListener taskPerformer = new ActionListener() { 
     public void actionPerformed(ActionEvent evt) { 
      //Empty the label here. This code will be called once the timeout of three seconds has been passed 
     } 
    }; 
    new Timer(delay, taskPerformer).start(); 
1
class runnable implements Runnable { 
    private Object obj; 
    public runnable(Object obj) 
    { 
     this.obj = obj; 
    } 
    public void run() { 
     try { 
      Thread.sleep(3000); 
      this.obj.setText("");//right here just execute your method 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out.println("Hello from a thread!"); //your code here 
    } 

} 

public class Test { 

    public static void main(String[] args){ 
     Object myObject; 
     (new Thread(new runnable(myObject))).start(); 
    } 
} 

你可以啓動另一個線程來處理這個問題。只要在另一個線程中進行處理即可。睡3秒鐘,然後清除lbl。

這裏有一個例子展示它是如何工作的:

class runnable implements Runnable { 
    Test test; 
    public runnable(Test test) 
    { 
     this.test = test; 
    } 
    public void run() { 
     try { 
      Thread.sleep(3000); 
      this.test.test = "test2"; 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out.println("Hello from a thread!"); 
    } 

} 

public class Test { 
    public String test = "test"; 
    public static void main(String[] args) throws InterruptedException{ 
     Test test = new Test(); 
     System.out.println(test.test); 
     (new Thread(new runnable(test))).start(); 
     Thread.sleep(4000); 
     System.out.println(test.test); 
    } 
} 

****************************** ****************************** UPDATE ******************* ******************************************

class runnable implements Runnable { 
    Test test; 
    public runnable(Test test) 
    { 
     this.test = test; 
    } 
    public void run() { 
     try { 
      Thread.sleep(3000); 
      this.test.label.setText("This is a test."); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out.println("Hello from a thread!"); 
    } 

} 

public class Test { 
    public String test = "test"; 
    JLabel label = new JLabel("Test"); 
    JFrame frame = new JFrame(); 
    JButton button = new JButton(); 
    public static void main(String[] args) throws InterruptedException{ 
     Test test = new Test(); 
     test.label.setText("Test"); 
     test.button.setText("Test Button"); 
     test.button.setSize(50, 50); 
     test.frame.setSize(500, 500); 
     test.frame.add(test.button); 
     test.frame.add(test.label); 
     test.frame.setVisible(true); 
     test.button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       // TODO Auto-generated method stub 
       System.exit(0); 
      } 

     }); 
     (new Thread(new runnable(test))).start(); 
    } 
} 
+0

如果OP在Swing中需要一個定時器,那麼這不是Swing提供自己的定時器的最佳方式。更不用說其他thead的代碼不會在調度線程上運行。 – 2014-12-03 21:34:24

+0

他可以使用定時器或啓動另一個線程任何一種方式工作 – brso05 2014-12-03 21:34:59

+0

1.爲什麼要使用線程,如果有更簡單的方法來做到這一點? 2.第二個線程中的代碼不能更新Swing,除非你在EDT(另一個Runnable)上調用它,所以上面的例子是錯誤的,除非你添加它。 – 2014-12-03 21:38:54

0

Your問題是你的屏蔽UI線程。它不能更新任何內容和主循環中斷。您可以像其他人已經回答的那樣使用timer對象完成您的目標,或者如果您不想讓自己的線程也可以執行相同的操作。