Java - 기본기

25. Java Swing 과 JFrame, Graphics

TerianP 2022. 4. 5.
728x90

Java Swing 이란 GUI 프로그래밍에 필요한 각종 라이브러리와 클래스들을 묶어놓은 것으로 JAVA 로 GUI 프로그래밍을 하게 된다면 한번쯤 보게 된다. 다양한 라이브러리들을 임포트해서 사용하는데 그 중에서도 JFrame 을 상속받아서 사용하면 보다 편하게 GUI 프로그래밍이 가능하다.

0. JFrame 와 Frame 의 차이점은 분명 존재!!

  • Frame - AWT ———> 업그레이드 ======⇒ JFrame - Swing
  • JFrame 을 상속받아서 사용할때 기본으로만 실행하면, 말 그대로 기본 동작만 있기 때문에 최소화, 최대화, x 버튼(창 닫기 버튼) 사용 등이 가능하나, X 버튼의 경우 실제로 눌렀을 때 꺼지게하기위해서는 직접 설정해야함
    • 참고로 Frame 이 아닌 JFrame 의 클래스를 사용하기 위해서는 앞에 J 를 붙인다.
    JFrame 의 모든 패키지는 Frame 과 차별을 두기 위해 앞에 J를 붙인다
    import javax.swing.JButton;
    import javax.swing.JFrame; 
    요렇게
    

1.Window 창

아래의 모든 버튼, 라벨, 텍스트 필드 등의 컴포넌트는 대부분 비슷한 메소드를 갖는다.

  • setSize : 사이즈 설정
  • setLocation : 위치 설정
  • setBackground(Color 객체) 혹은 setBackground(new Color(RGB값)) : 색깔 설정
  • setBounds : 넓이 높이 x y 한번에 설정 가능 => 위에서의 setSize + setLocation
  • 컴포넌트 추가는 add
  • 이벤트와 관련된 addXXXListener 은 XXXListener 인터페이스를 구현한 구현체를 매개변수로 갖는다.
    • addActionListener → ActionListener
    • addWindowListener → WindowListener

1) 버튼과 이벤트

  • Button : 이벤트 소스
    • 버튼에 이벤트를 달려면 addActionListen 을 사용함
    • 이때 addActionListener 은 매개변수로 ActionListener 를 갖는데 ActionListener 는 인터페이스이기 때문에 반드시 구현체가 필요함
  • Handler : 이벤트 발생 시 일어날 동작 정의
  • EventListener ⇒ ActionListener : 이벤트가 일어나는 상황을 확인해주는 인터페이스
    • 인터페이스이기 때문에 반드시 구현체가 필요함
    • 구현체를 만들기 위해서 따로 Handler 클래스를 만들어도 되나, 굳이 그럴 필요 없이 MyWinEx 클래스에서 ActionListener 인터페이스를 가져와도 상관없음
  • 버튼 생성자에 ImageIcon 인스턴스를 매개변수로 넣어서 버튼에 이미지를 씌울 수 있다.
    • setIcon 으로 이미지를 변경할 수도 있따.
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

// 1. event 소스 결정 : btn
// 2. event 소스에 감지기를 부착 : ActionListener
// 3. handler 정의 : 이벤트 발생 시 일어날 동작 정의

public class MyWinEx1 extends Frame{
	String name;
	Button btn;
	
	MyWinEx1(String title){
		super(title); // String 매개변수가 있는 부모 생성자 호출
		setVisible(true);
		setSize(800,600);
		setLocation(400,300);
		
		btn = new Button("plz...Click me!!");
		add(btn);
		
		Handler hd = new Handler();
		
		// addActionListener 의 매개변수는 ActionListener 인터페이스의 구현체가 와야함
		btn.addActionListener(hd); 
		
	}
	
	public static void main(String[] args) {
		MyWinEx1 mw = new MyWinEx1("new window");
		
		
	}
}

// ActionListener 는 인터페이스이기 때문에 Handler 클래스를 통해 구현해줌
class Handler implements ActionListener {

@Override
// // e.getActionCommand 는 '버튼의 이름'을 가져온다
if(e.getActionCommand().equals("Yes")) {
		// TODO Auto-generated method stub
			System.out.println("이벤트 Start!! : Im Yes");
		}else {
			System.out.println("이벤트 Close!! : Im No");
		}
	
}
  • 따로 구현체 클래스 생성 X
public class MyWinEx3 extends Frame implements ActionListener {

	Button exitBtn = new Button("Exit");
	
	MyWinEx3(){

		this.setTitle("종료 이벤트");
		this.setSize(850, 650);
		this.setLocation(100, 100);
		this.setVisible(true);
		
		this.add(exitBtn, "South");

		// 매개변수에 자기 자신을 의미하는 this 를 가져와서 넣어도 상관없음
		exitBtn.addActionListener(this);
	}
	public static void main(String[] args) {
		MyWinEx3 mw = new MyWinEx3();
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("삐빅! 프로그램을 종료합니다!");
		System.exit(0);
	}
}
  • 버튼으로 배열하기
    • 아래처럼 하면 버튼 배열을 만들어서 삽입 가능
Button[] btn = new Button[50];
	FlowLayout flow = new FlowLayout();
	Quiz_02(){
		this.setVisible(true);
		this.setBounds(200, 200, 800, 600);
		this.setLayout(flow);
		
// 		아래 내용이 가능함
//		btn[0] = new Button("hah");
//		this.add(btn[1]);
		
		// 따라서 이것도 가능!
		for(int i=0; i<btn.length; i++) {
			this.add(btn[i] = new Button("Button Array index : "+i));
		}
	}

 

2) 레이아웃 : Layout

  • 레이아웃은 일명 배치 관리자라고 불림
  • 이는 레이아웃이 알아서 버튼의 위치를 배치해주고 관리해주기 때문
  • setLayout 의 매개변수에 레이아웃을 객체를 넣는다면, 해당 레이아웃 - 배치 관리자 - 를 통해서 컴포넌트를 관리하게 되지만 null 로 둔다면 직접 컴포넌트의 크기를 정하고 관리해주어야 한다
  • 생성자에 int, int, int 를 넣어서 위치를 지정 가능하다.
// 배치 관리자 변경 : Flow 형식으로 컴포넌트를 배치해줌
		FlowLayout layout = new FlowLayout();
		setLayout(layout);

// 배치 관리자는 창의 크기 위치를 자동으로 조절해줌
		// 1. 배치관리자 : Frame => BorderLayout 기본
		// FlowLayout로 배치 관리자 변경 : Flow 형식으로 컴포넌트를 배치해줌
//		FlowLayout layout = new FlowLayout();
//		setLayout(layout);
		
		// 2. 배치관리자 사용 X
		setLayout(null);
		// 배치관리자를 사용하지 않는 경우 직접 버튼의 크기와 위치를 지정해두어야함
		// 버튼 크기
		btnYes.setSize(100,60);
		btnNo.setSize(100,60);
		
		// 버튼 위치
		btnYes.setLocation(200, 450);
		btnNo.setLocation(450, 450);

CardLayout

  • CardLayout 을 사용하면 내가 원할때마다 컴포넌트를 바꿔 끼울 수 있음
    • 메소드는 show(getContentPane(), “컴포넌트명”)
  • 주로 패널을 만들어서 패널에 각종 컴포넌트를 끼워 둔 다음, 해당 패널을 바꿔끼우는 방식으로 사용 가능
    • 이때 패널을 만들때 JPanel.add(컴포넌트, “패널명”) 을 적어주면 cardlayout 메소드에서 컴포넌트 명에 패널명을 넣어주면 해당 패널을 가져오게 됨

3) Label : 라벨

  • 일종의 이름표 ⇒ 보통 글자 출력을 위해 사용됨
Label label = new Label("오늘은 무슨 요일?", Label.CENTER);
	
	
	MyWinEx3(){

		// 전체 틀
		this.setTitle("종료 이벤트");
		this.setSize(850, 650);
		this.setLocation(100, 100);
		this.setVisible(true);
		this.setLayout(null);
			
		
		// label
		label.setSize(200,60);
		label.setLocation(330, 250);
		label.setBackground(Color.green);

		/*
		 * 이벤트 :  
		 * 이벤트 실행시 인터페이스를 상속받았다면 
		 * 매개변수에 자기 자신을 의미하는 this 를 가져와서 넣어도 상관없음
		 */		
		exitBtn.addActionListener(this);
		
		this.add(exitBtn);
		this.add(label);

4) TextField : 텍스트 필드(1줄), TextArea : 여러줄

  • 문자를 입력하고 편집할 수 있는 칸
  • gettext() : 입력된 텍스트 가져올 수 있음
  • setEchoChar : 입력된 값을 지정한 Char 로 표시함
  • settext(String text) : 내용 입력
import java.awt.TextField;

public class MyWinEx3 extends Frame implements ActionListener {

	TextField tf = new TextField();
	
	
	MyWinEx3(){

		// 전체 틀
		this.setTitle("종료 이벤트");
		this.setSize(850, 650);
		this.setLocation(100, 100);
		this.setVisible(true);
		this.setLayout(null);
			
		// textField
		tf.setSize(550, 60);
		tf.setLocation(150, 450);
				
		this.add(tf); // 컴포넌트 추가
		
		
	}
	public static void main(String[] args) {
		MyWinEx3 mw = new MyWinEx3();
	}
	
}
  • 이런식으로 사용 가능
@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if(e.getActionCommand().equals("Login")) {
			System.out.println("Login 시도 중...");
			System.out.println("id : "+idTF.getText());
			System.out.println("passwd : "+passwdTF.getText());
		}else {
			System.out.println("Login 정보 리셋");
			idTF.setText("");
			passwdTF.setText("");
			
		}
	}

5) 윈도우 창 자체 이벤트 관련 - WindowListener 메서드

  • WindowListener 을 매개변수로 갖는다.
  • 각각의 메서드는 아래와 같다.
public class MyWinEx4 extends Frame implements WindowListener {
	
	MyWinEx4(){
		this.setSize(800,600);
		this.setLocation(100,100);
		this.setVisible(true);
		
		// 윈도우 창에 변화를 감지
		addWindowListener(this);
		// XXXListener 인터페이스를 구현한 객체를 매개변수로 갖는다
	}
	
	
	public static void main(String[] args) {
		MyWinEx4 mw = new MyWinEx4();
		
	}

	@Override
	public void windowOpened(WindowEvent e) {
		// TODO Auto-generated method stub
		System.out.println("창이 열릴때 호출");
	}

	@Override
	public void windowClosing(WindowEvent e) {
		// TODO Auto-generated method stub
		System.out.println("창이 종료 중일때 호출");
		System.out.println("X 버튼 눌렀을 때");
		System.exit(0);
	}

	@Override
	public void windowClosed(WindowEvent e) {
		// TODO Auto-generated method stub
		System.out.println("창이 종된 후에 호출");
	}

	@Override
	public void windowIconified(WindowEvent e) {
		// TODO Auto-generated method stub
		System.out.println("창이 아이콘화 되었을 때 호출");
	}

	@Override
	public void windowDeiconified(WindowEvent e) {
		// TODO Auto-generated method stub
		System.out.println("창이 비 아이콘화 되었을 때 호출");
	}

	@Override
	public void windowActivated(WindowEvent e) {
		// TODO Auto-generated method stub
		System.out.println("창이 활성화 되었을 때 -> 선택되었을때");
	}

	@Override
	public void windowDeactivated(WindowEvent e) {
		// TODO Auto-generated method stub
		System.out.println("창이 비활성화 되었을 때 -> 비 선택되었을때");
	}

 

6) Font

  • Font 인스턴스를 생성하여 라벨과 텍스트 필드에 폰트를 설정할 수 있다
Font font = new Font("고딕",Font.BOLD,30);
		
		idTF.setFont(font);
		passwdTF.setFont(font);

 

7) Keyboard 이벤트

  • KeyListener
// 키보드 이벤트 : keyListener
		this.addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {
				// TODO Auto-generated method stub
			}

			@Override
			public void keyPressed(KeyEvent e) {
				// 키보드 누를때 이벤트
				int code = e.getKeyCode();
				System.out.println(code);
				
				// 버튼의 x 좌표 , y 좌표
				int btnX = btn.getX();
				int btnY = btn.getY();
				System.out.println("btnX : "+btnX);
				System.out.println("btnY : "+btnY);
			}

			@Override
			public void keyReleased(KeyEvent e) {
				// 키보드 뗄 때 이벤트
//				int code = e.getKeyCode();
//				System.out.println(code);
			}
			
		});

 

8) JScrollPane : 스크롤 바

  • JScrollPane 는 조금 특이하게 동작함
  • 기본 layout : flow
  • JScrollPane 와 다른 컴포넌트를 바로 JFrame 에 붙이는게 아닌 다른 컴포넌트를 JScrollPane에 붙이고 그 후 JScrollPane 만 JFrame 에 붙는 것

 

9) JOptionPane

  • showConfirmDialog : 생성자는 다음 4가지를 순서대로 넣는다.
    • 어느 컴포넌트에서 나타나게 할건지, 어떤 메시지를 출력하는지, 창제목, optionType
    • 이때 optionType 은 여러가지가 있는데 자세한건 JOptionPane 에 static final 로 정의된 내용 - 상수 - 를 참조하자
if(text.length() !=0) {
				// yes -> 저장
				// no -> jta 내용 지우기
				int result = JOptionPane.showConfirmDialog(this, "저장할래?", "메모장",
						JOptionPane.YES_NO_CANCEL_OPTION);
				System.out.println(result);
				
				if(result == JOptionPane.YES_OPTION) {
					// 저장한다
					System.out.println("저장 gogo!");
				}
			}

 

10) JPanel

  • 얘는 일종의 배경판 느낌, 배경 판에 여러 컴포넌트를 붙이고, 다시 그 판을 Frame 에 붙임
  • 기본 layout : flow
  • JPanel 사용하려면 전체창을 불러오는 코드보다 위에 있어야함

11) ImageIcon

  • 이미지 아이콘 클래스를 사용해 버튼에 이미지를 넣을 수 있다.
ImageIcon img = new ImageIcon("이미지 경로");

 

2. Graphics - paint

  • paint 메소드를 통해서 그래픽을 창에 그릴 수 있다.
  • 그래픽을 창에 그린다 paint 라는것은 그림, 사진 이런것 뿐만 아니라 선, 원, 사각형, 글씨 등등 전체적인 부분에서의 그래픽적인 부분을 그린다라는 것
  • 이때 사용되는 그래픽을 그리는 메소드는 대표적으로 총 3가지로 paint, reapint, update 가 있다.
    • 순서는 대략 paint → (update) → repaint

메소드 설명

paint 그래픽적 요소를 그리는 메소드 이 안에서 내가 원하는 그래픽적 요소를 넣어준다
repaint repaint 메소드는 기존의 paint 메소드를 한번 더 부르는 메소드. 단, 기존의 화면을 지우고 다시 paint을 호출하는 방식을 사용한다.
update update 메소드는 repaint 메소드에서 기존의 그래픽 paint 메소드를 지우는 작업을 해주는 메소드. repaint 를 사용할 때 내부적으로 호출된다.

1) paint, update,

@Override
	public void paint(Graphics g) {
		// TODO Auto-generated method stub
		// 100, 100, 200, 200 을 지나는 선
		g.drawLine(100,100,200,200);
	
	}
	
	// update 는 repaint 사용시 내부에서 호출되는 기존의 paint 를 지우는 메소드
	@Override
	public void update(Graphics g) {
		paint(g);
	}

2) 이미지 넣기

  • Image 클래스를 통해 이미지 객체 생성 → toolkit 를 사용해서 이미지 위치를 지정 → drawImage 를 통해 그래픽 그리기
// toolkit 객체
Toolkit tool = Toolkit.getDefaultToolkit();
		
// 이미지 객체 가져오기
img = tool.getImage("src/images/baby.jpg");

// paint 에서 사용하기
@Override
	public void paint(Graphics g) {
		// TODO Auto-generated method stub
		g.drawImage(img, 10, 10, 800, 600, this);
	}

댓글