2013-06-28 61 views
-1

我想用的Java Swing計時器更換Thread.sleep(),我聽到很多對顯卡更好。定時器中的Java Swing

之前,我有一些東西成立這樣的,但它是與圖形的干擾。

while(counter < array.size){ 
Thread.sleep(array.get(counter).startTime); 
//do first task 
Thread.sleep(array.get(counter).secondTime); 
//do second task 
Thread.sleep(array.get(counter).thirdTime); 
//do third task 
counter++ 
} 

現在,我試圖用其中之一來代替每個Thread.sleep(),然後我在此之後所發生的真實事件,但它似乎並沒有在所有等待。

int test = array.get(counter).time; 
ActionListener taskPerformer = new ActionListener(){ 
public void actionPerformed(ActionEvent evt){ 
} 
}; 
Timer t = new Timer(test, taskPerformer); 
t.setRepeats(false); 
t.start(); 

基本上,我該如何確保程序將等待而不給它任何代碼執行內部的定時器?謝謝!

+2

那是......不是定時器做。 –

+0

好的,謝謝。如果你知道怎麼做,那麼你能回答我如何在循環中發生3個連續任務,並且時間在他們之間? – Yesha

+3

你不希望程序等待。我們的想法是,每一個計時器滴答它會改變程序的狀態時某種方式,然後畫和下一個計時器開始... – MadProgrammer

回答

5

答案歸結爲它是什麼你想達到...

進口的是記住,Swing是單線程環境,也就是說,它希望所有的相互作用,變更,修改,從事件調度線程的上下文中完成對UI的更新和創建。

阻止EDT的任何操作(例如sleepwait等)將阻止EDT重新繪製UI或響應新事件。實現這一

的一種方式是通過使用javax.swing.Timer

這是使用3個定時器鏈接在一起非常簡單的例子。就個人而言,我會用配置很短的時間刻度,並檢查是否出現所需的延遲時間,然後相應地更改狀態,一個計時器,但這種跨獲取點......

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class SimpleTimer { 

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

    public SimpleTimer() { 
     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 class TestPane extends JPanel { 

     private Timer red; 
     private Timer green; 
     private Timer yellow; 
     private Color color = Color.GREEN; 

     private Point spot; 

     public TestPane() { 
      red = new Timer(500, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        color = Color.RED; 
        green.start(); 
        repaint(); 
       } 
      }); 
      green = new Timer(2000, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        color = Color.GREEN; 
        yellow.start(); 
        repaint(); 
       } 
      }); 
      yellow = new Timer(1000, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        color = Color.YELLOW; 
        red.start(); 
        repaint(); 
       } 
      }); 
      red.setRepeats(false); 
      green.setRepeats(false); 
      yellow.setRepeats(false); 
      green.start(); 

      addMouseMotionListener(new MouseAdapter() { 
       @Override 
       public void mouseMoved(MouseEvent e) { 
        spot = e.getPoint(); 
        repaint(); 
       } 
      }); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      int radius = 20; 
      int x = (getWidth() - radius)/2; 
      int y = (getHeight() - radius)/2; 
      g2d.setColor(color); 
      g2d.fillOval(x, y, radius, radius); 

      if (spot != null) { 

       x = spot.x - 5; 
       y = spot.y - 5; 
       g2d.setColor(Color.RED); 
       g2d.drawOval(x, y, 10, 10); 
       g2d.setColor(Color.YELLOW); 
       g2d.fillOval(x, y, 10, 10); 

      } 

      g2d.dispose(); 
     } 
    } 
} 

另一種選擇是使用SwingWorker,這允許在後臺線程中執行某種處理(使EDT運行),但提供了可以簡單地將結果同步回EDT的方法。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingWorker; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class SimpleTimer { 

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

    public SimpleTimer() { 
     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 class TestPane extends JPanel { 

     private Color color = Color.GREEN; 

     private Point spot; 

     public TestPane() { 

      new Switcher().execute(); 

      addMouseMotionListener(new MouseAdapter() { 
       @Override 
       public void mouseMoved(MouseEvent e) { 
        spot = e.getPoint(); 
        repaint(); 
       } 
      }); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      int radius = 20; 
      int x = (getWidth() - radius)/2; 
      int y = (getHeight() - radius)/2; 
      g2d.setColor(color); 
      g2d.fillOval(x, y, radius, radius); 

      if (spot != null) { 

       x = spot.x - 5; 
       y = spot.y - 5; 
       g2d.setColor(Color.RED); 
       g2d.drawOval(x, y, 10, 10); 
       g2d.setColor(Color.YELLOW); 
       g2d.fillOval(x, y, 10, 10); 

      } 

      g2d.dispose(); 
     } 

     public class Switcher extends SwingWorker<Void, Color> { 

      @Override 
      protected void process(List<Color> chunks) { 
       color = chunks.get(chunks.size() - 1); 
       repaint(); 
      } 

      @Override 
      protected Void doInBackground() throws Exception { 

       while (true) { 

        publish(Color.GREEN); 
        Thread.sleep(2000); 
        publish(Color.YELLOW); 
        Thread.sleep(500); 
        publish(Color.RED); 
        Thread.sleep(2000); 

       } 

      } 

     } 

    } 
} 

退房Concurrency in Swing更多細節

+0

哇,這是真棒!非常感謝! – Yesha

+0

希望它可以幫助你,無論你試圖達成什麼 – MadProgrammer

+0

哦,它絕對會。這是一個字幕應用程序,可以瀏覽任何在網絡上具有可用的SRT(字幕)文件的視頻。 – Yesha