2012-02-01 31 views
0

我想用線程同時顯示很多動畫。 但它不起作用,第二個動畫在第一個結束時開始。 我使用線程,但可能是錯誤的方式,因爲我是初學者 這裏是我的代碼:用線程顯示動畫

public class Board extends JPanel{ 

    Mouse mouse; 
    ArrayList<Explosion> explosions; 

    public Board() {    
     mouse = new Mouse(this);   
     explosions = new ArrayList();  
     setDoubleBuffered(true);   
     this.addMouseListener(mouse); 
    } 

    public void addExplosion(Explosion e) { 
     explosions.add(e); 
     new Thread(explosions.get(explosions.indexOf(e))).start(); 
    } 

    public void removeExplosion(Explosion e) { 
     explosions.remove(e); 
    } 

    public void paint(Graphics g) { 
     super.paint(g); 

     for(int i=0; i<explosions.size(); i++) { 
      explosions.get(i).paintComponent(g); 
     } 

     Graphics2D g2d = (Graphics2D)g; 
     Toolkit.getDefaultToolkit().sync(); 
     g.dispose(); 
    } 
} 


public class Explosion extends JPanel implements Runnable{ 

    private BufferedImage img; 

    final int width = 320; 
    final int height = 320; 
    final int rows = 5; 
    final int cols = 5; 

    private int x,y; 

    private int cursor; 

    BufferedImage[] sprites = new BufferedImage[rows * cols]; 

    Board board; 

    public Explosion(Board board,int x, int y) { 
     this.board = board; 
     this.x = x; 
     this.y = y; 

     try { 
      try { 
       this.img = ImageIO.read(new File((this.getClass().getResource("files/explosion2.png")).toURI())); 
      } catch (URISyntaxException e) { 
       e.printStackTrace(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     cursor = 0; 

     for (int i = 0; i < rows; i++) { 
      for (int j = 0; j < cols; j++) { 
       sprites[(i * cols) + j] = img.getSubimage(
        j * (width/rows), 
        i * (height/cols), 
        width/rows, 
        height/cols 
       ); 
      } 
     } 
    } 

    public void run() {  
     ActionListener taskPerformer = new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
       cursor++; 
      } 
     }; 

     Timer timer = new Timer(50, taskPerformer); 

     while(cursor < ((rows*cols)-1)) {   
      timer.start(); 
      board.repaint();     
     } 
     timer.stop(); 

     board.removeExplosion(this); 
    } 

    public void paintComponent(Graphics g){ 
     Graphics2D g2d = (Graphics2D)g; 
     g2d.drawImage(sprites[cursor], x, y, this); 
     g.dispose();  
    } 
} 

感謝您的幫助

+3

不回答你的問題,而不是:'explosions.get(explosions.indexOf(E)) '相當於......'e'? – 2012-02-01 21:00:13

+1

爲了儘快提供更好的幫助,請發佈[SSCCE](http://sscce.org/)。 – 2012-02-02 01:14:05

+0

不是你的問題的答案,但「Swing程序應該重寫'paintComponent()'而不是重寫'paint()'。」 - [在AWT和Swing中繪製:繪製方法](http://java.sun。 COM /產品/ JFC/TSC /用品/繪畫/ index.html的#回調)。 – trashgod 2012-02-02 01:15:56

回答

2

,更新的GUI的任何代碼應與相關的線程上運行GUI。爲了從不同的線程這樣做,像你的情況,你將需要使用SwingUtilities.InvokeLater

SwingUtilities.InvokeLater(new Runnable() { 
    public void run() { 

     // code to update the GUI goes here 
    } 
}); 
+0

但是更新GUI的代碼,簡單的調用repaint()? – guillaume 2012-02-01 21:12:36

+1

@guillaume yout繪畫是從Runnable#Thread調用的,然後repaint()會被包裝到invokeLater中,並且沒有人知道在另一個方法上隱藏了什麼可能成爲invokeAndWait() – mKorbel 2012-02-01 21:16:39

+1

即使我有'while(cursor <((rows * cols) -1)) \t \t \t {\t \t \t \t \t timer.start(); \t \t \t嘗試{ \t \t \t \t SwingUtilities.invokeAndWait(新的Runnable(){ \t \t \t \t公共無效的run(){ \t \t \t \t \t board.repaint(); \t \t \t \t \t} \t \t \t \t}); \t \t \t}趕上(例外五){ \t \t \t \t} \t \t \t \t \t}' 它不工作, – guillaume 2012-02-01 21:26:30