2013-04-22 122 views
1

我有一個用於擴展動畫的JPanel的類中的Timer,並且ActionListener偵聽它並使actionPerformed運行,它會在需要時重繪並停止計時器。但啓動定時器animatePanel的方法會在定時器運行時繼續執行,這是我不想要的。我希望它等到定時器停止返回。如何在執行代碼之前等待計時器停止?

定時器是在類的構造函數初始化這樣的:

timer = new Timer(5, taskPerformer); 

這是它做什麼。我有話通話animatePanel():

private ActionListener taskPerformer = new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
     ... 
     if (some conditions){ 
      ... 
      timer.stop(); 
      ... 
      return; 
     } 

     ... 
    } 
}; 

private void animatePanel() { 
    ... 
    timer.start(); 
    System.out.println("Timer stopped."); //always executes before the timer has stopped :(
    //then returns and lets the rest of my program run while the timer is still going, which is BAD 
} 

定時器工作正常,只是在某些情況下,animatePanel()也將很快恢復,讓我的程序運行的剩餘部分,造成的問題。

+0

你能否介紹計時器變量的聲明? – 2013-04-22 01:56:07

+0

爲了更快得到更好的幫助,請發佈[SSCCE](http://sscce.org/)。 – 2013-04-22 01:56:27

+0

如果你從EDT的環境中啓動計時器,那麼這將炸燬在你的臉上,只是說... – MadProgrammer 2013-04-22 01:57:22

回答

1

你不能在事件分派線程的上下文中做到這一點,這樣做會讓你的應用程序掛起!

定時器必須在單獨的Thread中啓動。這可以讓您利用線程監視API。

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class WaitForTimer { 

    public static void main(String[] args) { 
     new WaitForTimer(); 
    } 

    public WaitForTimer() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public static class TestPane extends JPanel { 

     protected static final Object WAIT_FOR = new Object(); 
     private Timer timer; 
     private int tickCount = 0; 
     private JLabel ticks; 
     private JButton start; 

     public TestPane() { 
      timer = new Timer(250, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        tickCount++; 
        if (tickCount > 10) { 
         tickCount = 0; 
         timer.stop(); 
         synchronized (WAIT_FOR) { 
          WAIT_FOR.notifyAll(); 
         } 
         start.setEnabled(true); 
        } 
        ticks.setText(String.valueOf(tickCount)); 
       } 
      }); 
      timer.setRepeats(true); 
      timer.setCoalesce(true); 

      ticks = new JLabel("..."); 
      start = new JButton("Start"); 

      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridwidth = GridBagConstraints.REMAINDER; 
      add(ticks, gbc); 
      add(start, gbc); 

      start.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        start.setEnabled(false); 
        new Thread(new Runnable() { 
         @Override 
         public void run() { 
          System.out.println("Starting timer..."); 
          timer.start(); 
          synchronized (WAIT_FOR) { 
           try { 
            WAIT_FOR.wait(); 
           } catch (InterruptedException ex) { 
           } 
          } 
          System.out.println("Timer finished..."); 
         } 
        }).start(); 
       } 
      }); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 
    } 
} 
相關問題