1. 🔥 paintComponent

지금까지 배운 다양한 컴포넌트들은 해당 컨테이너 내에서 그림을 그리며(색칠)하며 호출된다.

디폴트로 컴포넌트는 paintComponent라는 메서드를 호출한다.

import java.awt.Graphics; // Graphics클래스

import javax.swing.JFrame;
import javax.swing.JPanel;

class DrawingInSwingPanel extends JPanel{
    DrawingInSwingPanel(){

    }
    @Override // paintComponent메서드 오버라이딩
    public void paintComponent(Graphics g) {
        super.paintComponent(g); // 부모메서드 호출
        System.out.println("paint");
    }
}

public class App extends JFrame {
    App(){
        setTitle("component Draw");
        setSize(600,600);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        add(new DrawingInSwingPanel());

        setVisible(true);
    }
    public static void main(String[] args){
        new App();
    }
}
  • 이 코드를 실행 시키면 보는 것과 같이 GUI가 출력되는데 해당 창을 늘리기, 줄이기, 최대화, 최소화 등등 컴포넌트를 다시 그려야하는 상황이 온다면 해당 매서드가 호출된다.

  • 해당 메서드를 오버라이딩할 경우 말 그대로 재정의가 되기 때문에 해당 메서드의 디폴트 즉, 부모의 메서드가 실행되지 않는다.(위험) 따라서 super키워드를 통해 부모 메서드 호출 후 재정의

Graphics g

그림을 그린다는 것-> 해당 컴포넌트의 메모리의 구성요소(각 점의 메모리), 그래픽카드에 존재 하는 픽셀 메모리.. 그래픽카드에 접근하여 해당 메모리값을 바꾸는 것이 그림을 칠하는 방식이다.

그렇다면 사용자가 하드웨어의 접근까지 다뤄야 하는 것인가?

  • swing에서 paintComponent(Graphics g)를 자동으로 호출하며 Graphics라는 객체로 실제 이미지의 메모리로 연결해준다.

따라서 사용자는 g를 사용해서 컴포넌트에 그림을 그리면 된다..!

1.1. 실습 - 사각형 그리기

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawRect(100, 100, 100, 100);
        // 가로(위치),세로(위치),너비,높이
    }

1.2. 정리

  • 스윙의 기본 철학
    • 모든 GUI컴포넌트들은 자신의 모양을 스스로 그린다.
    • 컨테이너들은 자신을 그린 후, 그 위의 자식들에게 그리기를 지시한다.
  • public void paintComponent(Graphics g)
    • 스윙 컴포넌트가 자신의 모양을 그리는 메서드
    • JComponent의 메서드: 모든 스윙 컴포넌트가 이 메서드를 가지고 있음
    • 컴포넌트가 그려져야하는 시점마다 호출된다.(크기 변경, 최소화,최대화 등등)
  • Graphics객체
    • java.awt.Graphics
    • 컴포넌트 그리기에 필요한 도구를 제공하는 객체
      • 색상선택, 문자열 출력, 도형그리기, 도형 칠하기, 이미지 출력, 클리핑
    • 사용자가 원하는 모양을 그리고자 할 때 paintComponent(Graphics g)오버라이딩

1.3. 실습 - 폰트

//코드 수정할 것

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.RED); // 색 결정
        g.drawString("세종대학교", 100, 100);
        g.setColor(new Color(255,0,255)); // 새로운 컬러 만들어서 할당
        g.drawRect(100, 100, 100, 100);

        Font f = new Font("굴림",Font.ITALIC,50);
        //폰트 객체 만들기(글씨체, 타입, 크기)
        g.setFont(f);//폰트 적용
        g.setColor(Color.GREEN);
        g.drawString("폰트 테스트", 200, 200);
    }

폰트 및 글씨색을 결정하여 String을 그리는 모습이다.

1.4. 실습 - 도형 그리기

class DrawingInSwingPanel extends JPanel{
    DrawingInSwingPanel(){

    }
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Dimension size = this.getSize();
        int w = size.width;
        int h = size.height;
        g.setColor(Color.GREEN);
        g.drawLine(0, 0, w,h);
        g.setColor(Color.BLACK);
        g.drawRect(100, 100, 200, 200);
        g.drawOval(200, 200, 100, 100);
        g.drawRoundRect(200, 100, 100, 100, 10, 10);
    }
}

draw를 fill로 바꾸면 내부도 채워서 그릴 수 있다 ex) fillRect()

  • drawLine: 선 그리기
  • drawRect: 사각형 그리기
  • drawOval: 사격형에 내접하는 원 그리기
  • drawRoundRect: 모서리가 둥근 각형
  • 추가적인 draw..가 있다! 알아볼껏

Dimension

  • Dimension클래스는 사이즈를 담을 수 있는 클래스(getSize반환값)

추가(신기한거 만들기 예제…)

class DrawingInSwingPanel extends JPanel{
    DrawingInSwingPanel(){

    }
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Dimension size = this.getSize();
        int w = size.width;
        int h = size.height;
        int div = 40;
        float dw = (float)w/div;
        float dh = (float)h/div;
        for(int i = 0; i < div; i++){
            g.drawLine(0, (int)(dh*i), (int)(dw*i), h);
        }
        for(int i = 0; i < 10; i++){
          g.setColor(new Color(i*25, i*25, i*25));
          g.fillRect(200+10*i, 200+10*i, 200-i*20, 200-i*20);
        }
    }
}

1.5. 실습 - 마우스로 선 그리기

class DrawingInSwingPanel extends JPanel implements MouseListener{
    int x1,y1; //멤버 필드 선언 시작좌표
    int x2,y2; //종료 좌표

    DrawingInSwingPanel(){
        addMouseListener(this);  
    } 
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawLine(x1, y1, x2, y2); //선 그리기
    }
    public void mouseClicked(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {
        x1 = e.getX();
        y1 = e.getY();
    }
    public void mouseReleased(MouseEvent e) {
        x2 = e.getX();
        y2 = e.getY();
        repaint(); //paintComponent호출 요청
    }
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
}

paintComponent는 자동으로 호출되기 때문에 사용자가 직접 호출할 수 없다 하지만, 간접적으로 현재 컴포넌트를 다시 그려달라고 요청은 가능 repaint()

repaint는 이벤트 분배 쓰레드에 요청을 보낸다.

추가

  • revaildate(): 배치관리자에게 컴포넌트들을 다시 배치하도록 지시하는 컴포넌트

1.6. 실습 - 마우스로 선 그리기(여러개)

class DrawingInSwingPanel extends JPanel implements MouseListener{
    ArrayList<Integer> x1 = new ArrayList<>();
    ArrayList<Integer> x2 = new ArrayList<>();
    ArrayList<Integer> y1 = new ArrayList<>();
    ArrayList<Integer> y2 = new ArrayList<>();

    DrawingInSwingPanel(){
        addMouseListener(this);  
    } 
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for(int i = 0; i<x1.size();i++){
            g.drawLine(x1.get(i), y1.get(i), x2.get(i), y2.get(i));
        }
    }
    public void mouseClicked(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {
        x1.add(e.getX());
        y1.add(e.getY());
    }
    public void mouseReleased(MouseEvent e) {
        x2.add(e.getX());
        y2.add(e.getY());
        repaint(); // 중요
    }
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
}
  • 선이 생길때 마다 그 선을 저장해야 하므로 ArrayList를 사용하여 선분을 저장한다.

1.7. 정리

스윙의 페인트

  • void paint(Graphics g): 컴포넌트 자신과 모든 자손을 그리기 중요
    • 아래는 paint의 호출 순서
  • void paintComponent(Graphics g): 컴포넌트 자신의 내부모양 그리기
  • void paintBorder(Graphics g): 컴포넌트의 외곽 그리기
  • void paintChildren(Graphics g): 컴포넌트의 자식 그리기(컨테이너의 경우)

paint한다는 것은 처음부터 다시 그리는것..!

repaint()로 컴포넌트를 다시 그림..

1.8. 실습 - 선분 드래그, 색 선택

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

class MyPanel extends JPanel implements MouseListener, MouseMotionListener{
    private class ColorButton extends JButton{
        Color color;
        ColorButton(String str, Color c){
            super(str);
            color = c;
        }
        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            int w = getWidth();
            int h = getHeight();
            g.setColor(color);
            g.fillRect(2, 2, w - 4, h - 4);
        }
    }
    
    private class MyLine{
        private int x1,y1,x2,y2;
        private Color color = Color.BLACK;
        MyLine(int _x1,int _y1,int _x2,int _y2, Color _c){
            x1 = _x1;
            y1 = _y1;
            x2 = _x2;
            y2 = _y2;
            color = _c;
        }
        void draw(Graphics g){
            g.setColor(color);
            g.drawLine(x1, y1, x2, y2);
        }
        void setEncPosition(int _x,int _y){
            x2 = _x;
            y2 = _y;
        }
    }

    ArrayList<MyLine> lines = new ArrayList<>();
    Color color = Color.BLACK;

    MyPanel(){
        addMouseListener(this);
        addMouseMotionListener(this);
    
        ColorButton red = new ColorButton("r", Color.RED);
        ColorButton blue = new ColorButton("b", Color.BLUE);
        ColorButton green = new ColorButton("g", Color.GREEN);

        red.addActionListener((e) -> {color = red.color;});
        blue.addActionListener((e) -> {color = blue.color;});
        green.addActionListener((e) -> {color = green.color;});

        add(red);
        add(blue);
        add(green);
    }
    int x,y;
    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        for(int i = 0; i < lines.size(); i++)
            lines.get(i).draw(g);
    }
    public void mouseClicked(MouseEvent e) {}
    int mouseButton = -1;
    public void mousePressed(MouseEvent e) {
        mouseButton = e.getButton();
        if(e.getButton() == MouseEvent.BUTTON1)
            lines.add(new MyLine(e.getX(),e.getY(), e.getX(),e.getY(),color));
    }
    public void mouseReleased(MouseEvent e) {
        repaint();
        mouseButton = -1;
    }
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseDragged(MouseEvent e) {
        if(mouseButton == MouseEvent.BUTTON1){
            lines.get(lines.size() - 1).setEncPosition(e.getX(),e.getY());
            repaint();
        }
        
    }
    public void mouseMoved(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }
}

public class My extends JFrame{
    My(){
        setSize(500,500);
        setTitle("Title");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        add(new MyPanel());

        setVisible(true);
    }
    public static void main(String[] args){
        new My();
    } 
}

1.9. 실습 - 커브(선)그리기

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.awt.GridLayout;
import java.awt.Point;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


class MyPanel extends JPanel implements MouseListener, MouseMotionListener{
    private class ColorButton extends JButton{
        Color color;
        ColorButton(String str, Color c){
            super(str);
            color = c;
        }
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            int w = getWidth();
            int h = getHeight();
            g.setColor(color);
            g.fillRect(2, 2, w - 4, h - 4);
        }
    }
    
    private class MyLine{
        private int x1,y1,x2,y2;
        private Color color = Color.BLACK;
        MyLine(int _x1,int _y1,int _x2,int _y2, Color _c){
            x1 = _x1;
            y1 = _y1;
            x2 = _x2;
            y2 = _y2;
            color = _c;
        }
        void draw(Graphics g){
            g.setColor(color);
            g.drawLine(x1, y1, x2, y2);
        }
        void setEncPosition(int _x,int _y){
            x2 = _x;
            y2 = _y;
        }
    }

    ArrayList<MyLine> lines = new ArrayList<>();
    Color color = Color.BLACK;

    MyPanel(){
        setBackground(Color.GRAY);
        addMouseListener(this);
        addMouseMotionListener(this);
    
        ColorButton red = new ColorButton("r", Color.RED);
        ColorButton blue = new ColorButton("b", Color.BLUE);
        ColorButton green = new ColorButton("g", Color.GREEN);

        red.addActionListener((e) -> {color = red.color;});
        blue.addActionListener((e) -> {color = blue.color;});
        green.addActionListener((e) -> {color = green.color;});

        add(red);
        add(blue);
        add(green);
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        for(int i = 0; i < lines.size(); i++)
            lines.get(i).draw(g);
    }
    int mouseButton = -1;
    public void mousePressed(MouseEvent e) {
        mouseButton = e.getButton();
        if(e.getButton() == MouseEvent.BUTTON1)
            lines.add(new MyLine(e.getX(),e.getY(), e.getX(),e.getY(),color));
    }
    public void mouseReleased(MouseEvent e) {
        repaint();
        mouseButton = -1;
    }
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseDragged(MouseEvent e) {
        if(mouseButton == MouseEvent.BUTTON1){
            lines.get(lines.size() - 1).setEncPosition(e.getX(),e.getY());
            repaint();
        }
        
    }
    public void mouseMoved(MouseEvent e) {}
    public void mouseClicked(MouseEvent e) {}
}

class MyPanelCur extends JPanel implements MouseListener, MouseMotionListener{

    private class MyCurve{
        ArrayList<Point> pts = new ArrayList<>();
        Color color;
        MyCurve(){
            color = new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));
        }
        void draw(Graphics g){
            // 점그리기
            // Iterator<Point> it = pts.iterator();
            // while(it.hasNext()){
            //     Point p = it.next();
            //     g.fillOval(p.x-1, p.y-1, 3, 3);
            // }
            g.setColor(color);
            for(int i = 0; i < pts.size()-1 ; i++){
                Point p1 = pts.get(i);
                Point p2 = pts.get(i+1);
                g.drawLine(p1.x, p1.y, p2.x, p2.y);
            }
        }
        void addPoint(int _x,int _y){
            pts.add(new Point(_x,_y));
        }
    }
    ArrayList<MyCurve> curves = new ArrayList<>();
    MyPanelCur(){
        addMouseListener(this);
        addMouseMotionListener(this);
        setBackground(Color.LIGHT_GRAY);
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        for(int i= 0;i<curves.size();i++)
            curves.get(i).draw(g);
    }
    public void mousePressed(MouseEvent e) {
        MyCurve c = new MyCurve();
        c.addPoint(e.getX(), e.getY());
        curves.add(c);
        repaint();
    }
    public void mouseReleased(MouseEvent e) {
        MyCurve c = curves.get(curves.size()-1);
        c.addPoint(e.getX(), e.getY());
        repaint();
    }
    public void mouseDragged(MouseEvent e) {
        MyCurve c = curves.get(curves.size()-1);
        c.addPoint(e.getX(), e.getY());
        repaint();
    }
    public void mouseMoved(MouseEvent e) {}
    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
}

public class My extends JFrame{
    My(){
        setSize(1000,500);
        setTitle("Title");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new GridLayout(1,2));

        add(new MyPanel());
        add(new MyPanelCur());

        setVisible(true);
    }
    public static void main(String[] args){
        new My();
    } 
}

태그: ,

카테고리:

업데이트:

댓글남기기