프로그래밍 언어/JAVA

스윙의 페인팅 메커니즘

· 코딩마이데이

스윙 컴포넌트이 그려지는 과정

스윙에서 페인팅의 기본 골격은 JComponent에 의해 구현되어 있습니다. 모든 스윙 컴포넌트들은 JCompent를 상속받음으로써 자연스럽게 스윙의 페인팅 메커니즘에 따라 가도록 됩니다. 스윙의 페인팅과 관련된 몇 개의 JComponent의 메소드는 다음과 같습니다.

스윙의 컴포넌트 페인팅 과정

 

repaint()

repaint()는 Component 클래스의 메서드로 자바 플랫폼에게 컴포넌트에 변화가 일어났으니 강제페인팅할 것을 지시하는 메서드입니다.

component.repaint(); // 컴포넌트 다시 그리기 지시

 

컴포넌트를 다시 그리기 위해서는 부모 컴포넌트부터 그리는 것이 좋습니다. 컴포넌트의 크기나 위치가 변경되었다면, 컴포넌트의 부모에게 컴포넌트의 이전 모양이나 이전 위치의 진상을 지우도록 해야 하기 때문입니다. 부모 컴포넌트(컨테이너)에서부터 다시 그리고자 하는 경우 다음과 같이 호출합니다.

component.getParent().repaint(); // 컴포넌트의 부모 컨테이너에게 다시 그리기 지시

 

revalidate()

revalidate()는 컨테이너의 배치관리자에게 자식 컴포넌트의 배치를 다시 하도록 자시하는 메소드입니다. 컨테이너에 컴포넌트를 새로 삽입하거나 삭제하여 컨테이너가 출력된 모양에 변화가 생겼다면 revalidate()를 호출하여 컨테이너를 다시 그리도록 해야 합니다. revalidate()가 내부적으로 repaint()를 부르지만 상황에 따라 잘 처리되지 않는 경우도 있습니다. 그러므로 컨테이너에 컴포넌트에 컴포넌트를 새로 삽입하거나 삭제하였다면, 다음 두 라인 모두 호출하여 컨테이너의 화면을 갱신해야 합니다.

container.revalidate(); // 컨테이너에 부착된 컴포넌트의 재배치 지시
container.repaint(); // 컨테이너 다시 그리기 지시

 

마우스를 이용하여 선 그리기(repaint() 사용)

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

public class GraphicsDrawLineMouseEx extends JFrame {
    private MyPanel panel = new MyPanel();

    public GraphicsDrawLineMouseEx() {
        setTitle("drawing Line by Mouse 예제");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setContentPane(panel);

        setSize(300, 300);
        setVisible(true);
    }

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

    // 선을 그릴 수 있는 패널을 구현한다.
    // 이 패널에 Mouse 리스너를 구현한다.
    class MyPanel extends JPanel {
        // 그려진 선을 모두 저장하기 위해 시작점은 vStart에
        // 끝점은 vEnd 벡터에 각각 저장한다.
        private Vector<Point> vStart = new Vector<Point>(); // Point만 저장하는 제네릭 벡터
        private Vector<Point> vEnd = new Vector<Point>(); // Point만 저장하는 제네릭 벡터

        public MyPanel() {
            // Mouse 리스너를 등록한다.
            // 이 리스너는 마우스 버튼이 눌러지면 마우스 포인터(시작점)를 vStart 벡터에 저장하고
            // 마우스 버튼이 놓여지면 마우스 포인터(끝점)를 vEnd 벡터에 기억한다.
            addMouseListener(new MouseAdapter(){
                public void mousePressed(MouseEvent e) {
                    Point startP = e.getPoint(); // 마우스 포인터를 알아낸다.
                    vStart.add(startP); // 시작점을 vStart에 저장한다.
                }
                public void mouseReleased(MouseEvent e) {
                    Point endP = e.getPoint(); // 마우스 포인터를 알아낸다.
                    vEnd.add(endP); // 끝점을 vEnd에 저장한다.

                    // 패널의 다시 그리기를 요청한다.
                    repaint();
                }
            });
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.BLUE); // 파란색을 선택한다.

            // 벡터의 크기만큼 루프 돌면서 선을 그린다.
            for(int i=0; i<vStart.size(); i++) { // vStart 벡터의 크기는 만들어진 선의 개수와 동일
                Point s = vStart.elementAt(i); // 벡터에 들어 있는 시작점을 알아낸다.
                Point e = vEnd.elementAt(i); // 벡터에 들어 있는 끝점을 알아낸다.

                // 시작점에서 끝점까지 선을 그린다.
                g.drawLine((int)s.getX(), (int)s.getY(), (int)e.getX(), (int)e.getY());
            }
        }
    }
}

 

[실행 결과]

 

 

JButton을 상속받아 새로운 버튼 생성

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

public class paintComponentEx extends JFrame {
    public paintComponentEx() {
        setTitle("새로운 버튼 만들기");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container c = getContentPane();
        c.setLayout(new FlowLayout());
        MyButton b = new MyButton("New Button");
        b.setOpaque(true);
        b.setBackground(Color.CYAN);
        c.add(b);
        setSize(250, 200);
        setVisible(true);
    }
    class MyButton extends JButton {
        public MyButton(String s) {
            super(s);
        }

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

            g.setColor(Color.RED);
            g.drawOval(0,0,this.getWidth()-1, this.getHeight()-1);
        }
    }

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

[실행결과]

'프로그래밍 언어 > JAVA' 카테고리의 다른 글

자바의 멀티스레딩  (7) 2025.08.07
스레드와 멀티태스킹  (2) 2025.08.05
클리핑(Clipping)  (3) 2025.07.30
이미지 그리기  (4) 2025.07.27
도형 그리기와 칠하기  (1) 2025.07.24