2013-06-12 72 views
0

我不確定如何解決這個問題,但是在做了一些閱讀和大量嘗試(失敗)之後,我決定向社區尋求幫助。我有表格A,打開並要求用戶輸入一個時間來延遲表格B的打開。目前我正在使用sleep()來做到這一點,但現在我想插入另一個對話框,以允許用戶在計時器用完之前中斷計時器並調出表格B.我相信正確的方法是使用wait()notify(),但我似乎無法圍繞衆多生產者和消費者模型的例子。任何幫助表示讚賞。Wait(),Notify(),定時器和Jbuttons

+4

不要阻塞EDT(Event Dispatch Thread) - 當發生這種情況時GUI將「凍結」。而不是調用'Thread.sleep(n)'爲延遲任務實現一個Swing'Timer'。有關更多詳細信息,請參見[Swing中的併發](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)。 –

回答

0

最簡單的方法是在做這樣的事情

Thread a = new Thread(new Runnable(){ 
    public void run(){ 
     //do whatever display 
     try{ 
     Thread.sleep(timeToShowBform); 
     } 
     catch(InterruptedException ex){ 
     //interrupted. 
     }finally{ 
     //show form B 
     SwingUtilities.invokeLater(...) 

    } 
}); 

class BRunnable implements Runnable{ 
public void run(){ 
//if clicked, then this runnable is called. 
a.interrupt(); 
} 
} 

線程a假設被阻塞在sleep,然後調用a.interrupt()它醒來a

+0

這將顯示外部的形式,這可能不是一個好主意。 – assylias

+0

@assylias是的,這就是爲什麼我使用'Thread'代替'a'而不是隻能運行的原因。 – Jatin

+1

我在說的是'finally'塊將在該線程上執行,而不是在EDT上執行。你應該只和EDT的GUI交互。 – assylias

1

javax.swing.Timer的完美工作。詳情請參閱How to Use Swing Timers。這裏有一個例子可以指導你正確的方向。

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.Timer; 
import javax.swing.*; 

public class TimerDemo extends JFrame implements ActionListener { 

    private Timer timer; 
    private JButton jbDoSomethingDelayed; 
    private JButton jbDoItImmediately; 

    public TimerDemo() {   
     setLayout(new FlowLayout()); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setTitle("Timer demo"); 

     jbDoSomethingDelayed = new JButton("Do something with a delay"); 
     jbDoItImmediately = new JButton("Do it. Do it NOW!"); 

     add(jbDoSomethingDelayed); 
     add(jbDoItImmediately); 

     jbDoItImmediately.setEnabled(false); 

     timer = new Timer(0, this); // we override delay later 
     timer.setRepeats(false); // we don't want it firing repeatedly 

     jbDoSomethingDelayed.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       String msg = "Enter delay and confirm dialog"; 
       JSpinner spinner = new JSpinner(new SpinnerNumberModel(5, 1, 10, 1)); 
       Object[] content = new Object[] {msg, spinner}; 
       int showConfirmDialog = JOptionPane.showConfirmDialog(TimerDemo.this, content, "Choose", JOptionPane.OK_CANCEL_OPTION); 
       if (showConfirmDialog == JOptionPane.OK_OPTION) { 
        // the important part 
        timer.setInitialDelay(((Integer)spinner.getValue()) * 1000);      
        jbDoSomethingDelayed.setEnabled(false); 
        jbDoItImmediately.setEnabled(true); 
        timer.start(); 
       } 
      } 
     }); 

     jbDoItImmediately.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       timer.stop(); 
       onTimerTimeout(); 
      } 
     }); 

     pack(); 
     setLocationRelativeTo(null); 
    } 

    public void actionPerformed(ActionEvent e) { 
     // called by timer on EDT, no worries here 
     onTimerTimeout(); 
    } 

    private void onTimerTimeout() { 
     jbDoSomethingDelayed.setEnabled(true); 
     jbDoItImmediately.setEnabled(false); 
     JOptionPane.showConfirmDialog(this, "You've done it now. No, really...", "It is done", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);   
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       TimerDemo demo = new TimerDemo(); 
       demo.setVisible(true); 
      } 
     }); 
    } 
} 
相關問題