JAVA공부 [9. JAVA SWING(3)]
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();
}
}
댓글남기기