2015-01-09 8 views
0

문제는이 같은 JPanel을 그릴 때입니다 : 왜 JPanel을 다시 작성해야합니까?

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    g.setColor (Color.CYAN); 
    g.fillRect(10,10,200,50); 
    g.setColor(Color.RED); 
    g.fillOval(50,50,50,50); 
} 

그래서 JPanel의이 시안 사각형과 붉은 타원을 그릴을 만들 때 경우. 예를 들어 타원을 이동하려면 전체 패널을 다시 칠해야합니다.

전체 객체를 다시 그릴 필요없이 2D 객체를 만들고 이동하고 변경할 수있게하려면 어떻게해야합니까?

답변

2

페인팅 프로세스를 이해하려면 Painting in AWT and SwingPerforming Custom Painting부터 살펴보십시오.

원한다면 패널 전체를 다시 칠할 필요가 없습니다. JPanel#repaint(int, int, int, int)을 사용하면 다시 칠할 영역을 지정할 수 있습니다.

이제 타원형을 포함하는 영역을 페인트 한 다음 현재있는 영역을 페인트해야하는 경우 이전 위치가 업데이트되었는지 확인하십시오. 그렇지 않으면 고스트가 발생합니다. ..

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package testball; 

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

public class TestBall { 

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

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

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

    public class TestPane extends JPanel { 

     private int x = 100 - 10; 
     private int y = 100 - 10; 
     private int delta = 4; 

     public TestPane() { 
      Timer timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        // Replace existing area... 
        repaint(x, y, 21, 21); 

        x += delta; 
        if (x + 20 >= getWidth()) { 
         x = getWidth() - 20; 
         delta *= -1; 
        } else if (x < 0) { 
         x = 0; 
         delta *= -1; 
        } 
        repaint(x, y, 21, 21); 
       } 
      }); 
      timer.start(); 
     } 

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

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.setColor(Color.RED); 
      g2d.drawOval(x, y, 20, 20); 
      g2d.dispose(); 
     } 

    } 

} 
1

새 주문에서 개체를 다시 칠해야합니다. Repaint는 또한 창을 최소화하고 최대화하는 경우 기본적으로 호출됩니다. 움직이는 동안 자동으로 패널을 업데이트하는 2D 객체를 만드는 한 가지 방법은 관찰자 패턴을 사용하는 것입니다. http://en.wikipedia.org/wiki/Observer_pattern

관련 문제