2013-06-12 3 views
0

나는이 문제에 접근하는 방법을 모르지만 일부 읽기와 많은 시도 (실패)를 한 후에 커뮤니티에 도움을 요청하기로 결정했습니다. 폼 A를 열어 사용자가 폼 B를 여는 데 걸리는 시간을 입력하도록 요청합니다. 현재이 작업을 수행하기 위해 sleep()을 사용하고 있지만 타이머가 만료되기 전에 사용자가 타이머를 중단하고 B 폼을 표시 할 수 있도록 다른 대화 상자를 삽입하고 싶습니다. 나는 이것을 할 올바른 방법이 wait()notify()과 같다고 생각하지만, 나는 생산자와 소비자 모델의 수많은 예를두고 머리를 감싸고있는 것처럼 보일 수 없다. 어떤 도움을 주셔서 감사합니다.Wait(), Notify(), 타이머 및 Jbuttons

+4

EDT (Event Dispatch Thread)를 차단하지 마십시오. GUI가 '고정'됩니다. 'Thread.sleep (n)'을 호출하는 대신 지연된 작업을위한 Swing 'Timer'를 구현합니다. 자세한 내용은 [동시성의 동시성] (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을 깨어 a.interrupt()를 호출에 sleep에서 차단한다고 가정 a처럼 뭔가를하고있을 것입니다.

+0

그건 아마도 좋은 생각이 아닌 EDT 외부 양식을 보여줄 것입니다. – assylias

+0

@assylias 예, 그렇기 때문에'Thread'를 runnable 대신'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); 
      } 
     }); 
    } 
} 
관련 문제