2012-02-01 6 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'? –

+1

Чтобы лучше помочь, опубликуйте [SSCCE] (http://sscce.org/). –

+0

Не ответ на ваш вопрос, но «программы Swing должны переопределять' paintComponent() 'вместо переопределения' paint() '." - [Живопись в AWT и Swing: методы Paint] (http: //java.sun. ком/продукция/JFC/TSC/статьи/живопись/index.html # обратных вызовов). – trashgod

ответ

2

Любой код, который обновляет графический интерфейс должен быть запущен на поток, связанный с графический интерфейс. Для этого из другого потока, как в вашем случае, вам нужно будет использовать SwingUtilities.InvokeLater:

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

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

Но какой код для обновления GUI, простой вызов перерисовать()? – guillaume

+1

@guillaume yout painting вызывается из Runnable # Thread, а затем repaint() будет завербован в invokeLater, и никто не знает, что скрыто в других методах, возможно, в invokeAndWait() – mKorbel

+1

Даже если у меня есть 'while (курсор <((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 общественности недействительным запуска() { \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

Смежные вопросы