2013-04-12 2 views
0

수천 번의 계산이 필요한 JPanel에서 이미지를 그리려하고 있으며 드로잉의 진행을 애니메이션화하려고합니다. 즉, 한 번에 100,000 회 반복하는 작업을 수행하는 대신 JPanel을 다시 칠하는 작업을 반복 할 때마다 다시 그리기를 원하고 잠깐 멈추고 이미지가 점차 나타나기 시작합니다. 그러나 JPanel을 새로 고칠 때마다 이전 드로잉이 지워 지므로 내 방법이 작동하지 않습니다. N 번째 반복에서 모든 (1..N-1) 계산을 복제하지 않고 어떻게 할 수 있습니까?Java에서 연속적으로 복잡한 이미지의 애니메이션 도면

이 예제를 고려하십시오. "눈"이 점차 화면에 나타나기를 원합니다. 그러나이 코드는 repaint()가 호출 될 때마다 이전의 모든 것들이 지워지므로 100,000 번째 "눈송이"만 표시합니다.

import javax.swing.*; 
import java.awt.*; 
import java.util.Random; 

class spanel extends JPanel{  
    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     g.drawLine(snow.x, snow.y, snow.x, snow.y); 
    } 
} 

class snow extends Thread { 

    static int x,y; 
    Random r = new Random(); 

    public void run(){ 

     JFrame sboard = new JFrame(); 
     sboard.setSize(600,600); 
     sboard.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     spanel mypanel = new spanel(); 
     sboard.add(mypanel); 
     sboard.setVisible(true); 

     for (int i=0;i<100000;i++){ 
      x=r.nextInt(600); 
      y=r.nextInt(600); 

      sboard.repaint();  
      try { 
       snow.sleep((long)10); 
      } catch (InterruptedException e) {}; 
     } 
    } 
} 

public class SnowAnim {  
    public static void main(String[] args) { 
     (new snow()).start(); 
    } 
} 

답변

0

당신은 아마도 버퍼에서 페인팅을 한 다음 paintComponent()에 버퍼의 현재 상태를 그려야합니다.

super.paintComponent(g);에 대한 호출을 건너 뛸 수 있지만 패널에서 시각적으로 다른 요소가 멈추는 것을 걱정해야합니다.

+0

감사합니다. super.paintComponent를 건너 뛰려고했는데 어떤 이유로 든 도움이되지 않았습니다. 버퍼에 드로잉하는 예제를 지적 해 주시겠습니까 (BufferedImage를 의미하는 것으로 가정)? 다시 복사하는 방법은 무엇입니까? –

+0

Andrew가 지적한 http://stackoverflow.com/questions/10628492/dynamic-graphics-object-painting-in-java/10628553#10628553을 참조하십시오. –

1

Custom Painting Approaches은 BufferedImage에서 그리는 방법을 보여줍니다. 포럼에 다른 예제도 많이 있습니다.

또한 애니메이션을 수행 할 때 스윙 타이머를 사용하여 애니메이션을 예약해야합니다.

1

N 번째 반복에서 모든 (1..N-1) 계산을 복제하지 않고 어떻게 수행 할 수 있습니까?

this example에 표시된대로 BufferedImage에 추가하십시오.

0

모두 감사합니다! 나는 그것을 알아. BufferedImage는 그것을 해결합니다. 기록을 위해, 여기 내 업데이트 된 코드가 있습니다. 또한 스레드 대신 스윙 타이머를 사용하여 애니메이션을 예약하는 Camickr의 제안을 구현합니다. 출력을 눈처럼 보일 수 있도록 약간의 미적인 변경을가했습니다. 다시 한번 감사드립니다!

import javax.swing.*; 
import java.awt.*; 
import java.awt.image.*; 
import java.util.Random; 
import java.awt.event.*; 

class spanel extends JPanel{ 
    int x,y,rad,i; 
    static Random r = new Random(); 
    BufferedImage image; 
    Graphics2D g2d; 
    Timer timer; 

    spanel(){ 
     image = new BufferedImage(600, 600, BufferedImage.TYPE_INT_ARGB); 
     g2d = (Graphics2D)image.getGraphics(); 
     setBackground(Color.black); 
     g2d.setColor(Color.white); 
     i=0; 
     ActionListener listener = new ActionListener() { 
      public void actionPerformed(ActionEvent ae) { 
       iterate(); 
      } 
     }; 
     timer = new Timer(10, listener); 
     timer.start(); 
    } 
    public void iterate(){ 
     x=r.nextInt(600); 
     y=r.nextInt(600); 
     rad=r.nextInt(5)+5; 
     g2d.fillOval(x, y, rad, rad); 
     repaint();  
     i++; 
     if (i==1000){timer.stop();} 
    } 
    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     g.drawImage(image,0,0,null); 
     } 
    } 


public class SnowAnim {  
    public static void main(String[] args) { 
     JFrame sboard = new JFrame(); 
     sboard.setSize(600,600); 
     sboard.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     spanel mypanel = new spanel(); 
     sboard.add(mypanel); 
     sboard.setVisible(true); 
    } 
} 
관련 문제