2014-12-03 186 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对象完成您的目标,或者如果您不想让自己的线程也可以执行相同的操作。