Super Kawaii Cute Cat Kaoani
본문 바로가기
💻 Programming/Java

[JAVA] 개념 정리(2)

by wonee1 2023. 10. 15.
728x90
이벤트 구동 프로그래밍

이벤트의 개념과 처리 과정
 

  • GUI프로그램은 이벤트가 실행 흐름을 결정하는 이벤트 구동 바익
  • 이벤트 구동 프로그램의 이벤트 처리과정
이벤트 소스-> 이벤트 발생(클릭)->JVM -> 이벤트 리스너 

이벤트 리스너

  • 발생한 이벤트를 처리하는 객체

이벤트 핸들러

  • 이벤트를 처리하는 이벤트 리스너의 멤버 메서드 

 
 

//package main; 패키지를 main 패키지를 만들어서 사용할 것 

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class Main extends JFrame {
	//private int cnt=0; //카운터 
	Main() {
		setTitle("이벤트 맛보기");

		ActionListener l = new ActionListener() {//리스너 생성 
			public void actionPerformed(ActionEvent e) {
				//cnt++;// 카운터 증가
				//System.out.println(cnt);
				System.out.println("버튼을 클릭했습니다.");
				
			}//버튼을 클릭하면 이벤트가 발생 
		};

		JButton b = new JButton("클릭");//버튼 생성 
		b.addActionListener(l);//리스너 추가 
		add(b);

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(260, 100);//크기 조절 
		setVisible(true);
	}

	public static void main(String[] args) {
		new Main();
	}
}
이벤트 클래스와 이벤트 리스너 

 
이벤트 클래스 소개 
 
이벤트 클래스는 이벤트 처리에 필요한 많은 정보를 제공. 예를 들어 사용자가 마우스를 클릭하면 클릭 여부 , 클릭된 컴포넌트 ,클릭된 위치 등과 같은 정보를 제공 
 
이벤트 클래스 종류 
 
의미 이벤트 

  • 버튼 클릭처럼 사용자가 의도하는 이벤트를 의미
  • 일부 스윙 컴포넌트에서만 발생 
  • 예 : ActionEvent, AdjustmentEvent, ItemEvent, TextEvent 등

 
저수준 이벤트

  •  의미 이벤트를 가능하게 하는 이벤트를 의미(의미 이벤트인 버튼 클릭은 마우스 이동, 마우스 누름, 마우스 놓기 등 여러 단계의 세부적인 이벤트로 구성) 
  • 모든 스윙 컴포넌트에서 발생 
  • 예 : ComponentEvent, ContainerEvent, FocusEvent, MouseEvent, KeyEvent 등
  •  

이벤트 리스너의 소개 
이벤트 소스와 이벤트리스너 
 

이벤트 소스에 이벤트 리스너 등록 
 

  • 이벤트 리스너는 매우 빠르게 처리되도록 가능한 짧게 작성될 필요
  • 이벤트 리스너가 하나의 스레드로 과다한 작업을 수행한다면 프로그램이 반응하지 않을 수도 있음 
  • 이벤트 처리 시간이 길다면 별도의 스레드에 맡기는 것이 바람직

 
 
이벤트 클래스와 이벤트 리스너 
 
 ActionEvent 
 
*JTextArea에서 사용자가 문자열을 입력한 후 엔터키를 누르면 ActionEvent가 발생한다. 

 
 
KeyEvent

MouseEvent
 

 
마우스의 움직임을 추적할 때는 시스템에 상당한 부담을 주기 때문에 자바는 MouseListener 인터페이스와 별도로 MouseMotionListener 인터페이스로 구분해 제공
 
 
이벤트 클래스와 주요 메서드
 
AdjustmentEvent

 

이벤트 처리 응용

 
원의 넓이 구하기 (ActionEvent 처리)
 

package main;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Main extends JFrame {
	JTextField t1, t2;
	JTextArea area;
	JButton cal, reset;
	JComboBox cb;

	Main() {
		setTitle("원 넓이 구하기");

		setLayout(new BorderLayout(10, 10));
		showNorth();
		showCenter();
		showSouth();

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300, 220);
		setVisible(true);
	}

	void showNorth() {
		JPanel p1 = new JPanel();
		JPanel p2 = new JPanel();
		JPanel panel = new JPanel(new GridLayout(2, 0));

		JLabel l1 = new JLabel("원의 반지름");
		JLabel l2 = new JLabel("원의 넓이");

		t1 = new JTextField(10);
		t2 = new JTextField(10);
		t2.setEnabled(false);

		p1.add(l1);
		p1.add(t1);
		p2.add(l2);
		p2.add(t2);
		panel.add(p1);
		panel.add(p2);

		add(panel, BorderLayout.NORTH);
	}

	void showCenter() {
		JPanel panel = new JPanel();

		area = new JTextArea(30, 20);
		area.setText("이 영역에 원의 넓이를\n계산하는 과정이 나타납니다.");
		area.setEditable(false);
		area.setForeground(Color.RED);

		panel.add(area);

		add(panel, BorderLayout.CENTER);
	}

	void showSouth() {
		String[] color = { "red", "blue" };

		JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));

		cal = new JButton("계산");
		cb = new JComboBox<String>(color);//색상 설정 
		reset = new JButton("리셋");

		panel.add(cal);
		panel.add(cb);
		panel.add(reset);
		add(panel, BorderLayout.SOUTH);

		ActionListener listener1 = e -> {
			if (e.getSource() == cal) {
				if (t1.getText().isEmpty()) // t1 텍스트 필드가 비어있다면
					// 반지름을 입력하세요 메세지를 area 텍스트 영역에 설정한다
					area.setText("반지름을 입력하세요!!!");
				else {
					String s = t1.getText();
					double radius = Double.parseDouble(s);// 문자열을 실수로 변환
					double result = radius * radius * 3.14;
					t2.setText("" + result);
					area.setText(radius + " * " + radius + " * 3.14 = " + result);
				}
			} else {
				t1.setText("");
				t2.setText("");
				area.setText("");
			} // reset 버튼을 클릭하면 초기상태로 리셋
		};// ActionListener 인터페이스를 구현한 람다 표현식

		cal.addActionListener(listener1);
		reset.addActionListener(listener1);
	}

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

KeyEvent 처리
 

package main;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Main extends JFrame {
	JTextField t1, t2;
	JTextArea area;
	JButton cal, reset;
	JComboBox cb;

	Main() {
		setTitle("원 넓이 구하기");

		setLayout(new BorderLayout(10, 10));
		showNorth();
		showCenter();
		showSouth();

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300, 220);
		setVisible(true);
	}

	void showNorth() {
		JPanel p1 = new JPanel();
		JPanel p2 = new JPanel();
		JPanel panel = new JPanel(new GridLayout(2, 0));

		JLabel l1 = new JLabel("원의 반지름");
		JLabel l2 = new JLabel("원의 넓이");

		t1 = new JTextField(10);
		t2 = new JTextField(10);
		t2.setEnabled(false);

		p1.add(l1);
		p1.add(t1);
		p2.add(l2);
		p2.add(t2);
		panel.add(p1);
		panel.add(p2);

		add(panel, BorderLayout.NORTH);

		KeyListener listener2 = new KeyListener() { // 입력하면 화면에 뭘 입력했는지 뜸
			public void keyTyped(KeyEvent e) {
				char keyChar = e.getKeyChar();
				if (Character.isDefined(keyChar))
					System.out.println(keyChar + "를 입력했습니다.");
			}

			public void keyReleased(KeyEvent e) {

			}

			public void keyPressed(KeyEvent e) {
				int keyCode = e.getKeyCode();
				if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_UP
						|| keyCode == KeyEvent.VK_DOWN) {
					System.out.println("뱡향키를 입력했습니다.");
				}
			}
		};
		t1.addKeyListener(listener2);
	}

	void showCenter() {
		JPanel panel = new JPanel();

		area = new JTextArea(30, 20);
		area.setText("이 영역에 원의 넓이를\n계산하는 과정이 나타납니다.");
		area.setEditable(false);
		area.setForeground(Color.RED);

		panel.add(area);

		add(panel, BorderLayout.CENTER);
	}

	void showSouth() {
		String[] color = { "red", "blue" };

		JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));

		cal = new JButton("계산");
		cb = new JComboBox<String>(color);
		reset = new JButton("리셋");

		panel.add(cal);
		panel.add(cb);
		panel.add(reset);
		add(panel, BorderLayout.SOUTH);

		ActionListener listener1 = e -> {
			if (e.getSource() == cal) {
				if (t1.getText().isEmpty())
					area.setText("반지름을 입력하세요!!!");
				else {
					String s = t1.getText();
					double radius = Double.parseDouble(s);
					double result = radius * radius * 3.14;
					t2.setText("" + result);
					area.setText(radius + " * " + radius + " * 3.14 = " + result);
				}
			} else {
				t1.setText("");
				t2.setText("");
				area.setText("");
			}
		};

		cal.addActionListener(listener1);
		reset.addActionListener(listener1);
		cb.addItemListener(e -> {
			int index = ((JComboBox) cb).getSelectedIndex();
			if (index == 0)
				area.setForeground(Color.RED);
			else
				area.setForeground(Color.BLUE);
		});
	}

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

 

어댑터 클래스 

기초
 
개발자가 필요한 추상 메서드만 구현하면 되도록 리스너에 대응하는 어댑터 클래스를 제공 (중요)
어댑터 클래스는 리스너 인터페이스에 포함된 모든 추상메서드를 빈 본체로 구현한 클래스에 불과 

추상클래스

Keyadapter
 

package main;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class Main extends JFrame {
	public Main() {
		setTitle("키 어댑터");

		JLabel l = new JLabel("", JLabel.CENTER);
		JTextField t = new JTextField(10);// 텍스트 필드 객체 , 텍스트를 입력받기위해

		add("North", t);
		add("Center", l);

		t.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {// VK_ENTER 엔터키가 눌렀는지 확인할 수 있다
					l.setText("입력한 문자열 : " + t.getText());
					// getText 텍스트에 입력된 문자열을 가져오는 메서드
					// l 레이블에 텍스트를 설정한다.

				} // keyAdapter 는 keyPressed 메서드를 재정의하여 키입력 처리
			}
		});

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300, 120);
		setVisible(true);
	}

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

 
MouseMotionAdapter 클래스 

package main;

import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Main extends JFrame {
	Main() {
		setTitle("마우스 이동 어댑터");

		JLabel label = new JLabel("움직이는 레이블");
		label.setForeground(Color.RED);
		add(label);

		addMouseMotionListener(new MyMouseMotionAdapter(label));

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300, 120);
		setVisible(true);
	}

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

class MyMouseMotionAdapter extends MouseMotionAdapter {
	JLabel label;

	public MyMouseMotionAdapter(JLabel label) {
		this.label = label;
	}

	public void mouseMoved(MouseEvent e) {
		label.setLocation(e.getX(), e.getY() - 50);
	}
}

 

이벤트와 메뉴 

메뉴의 구성 

메뉴의 계층구조 

 

 
 

package main;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;

public class Main extends JFrame implements ActionListener {
	Main() {
		setTitle("메뉴 구성하기");
		makeMenu();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300, 170);
		setVisible(true);
	}

	void makeMenu() {//메뉴 정의 
		JMenuItem item;
		KeyStroke key;

		JMenuBar mb = new JMenuBar();
		JMenu m1 = new JMenu("파일");
		m1.setMnemonic(KeyEvent.VK_F);// 단축키 ALT+F
		JMenu m2 = new JMenu("색상");
		m2.setMnemonic(KeyEvent.VK_C);// 단축키 ALT+C

		item = new JMenuItem("새 파일", KeyEvent.VK_N);
		item.addActionListener(this);
		m1.add(item);
		item = new JMenuItem("파일 열기", KeyEvent.VK_O);
		item.addActionListener(this);
		m1.add(item);
		m1.add(new JMenuItem("파일 저장"));
		m1.addSeparator();
		m1.add(new JMenuItem("종료"));

		item = new JMenuItem("파란색");
		key = KeyStroke.getKeyStroke(KeyEvent.VK_B, ActionEvent.CTRL_MASK);// 단축키 CTRL+B
		item.setAccelerator(key);
		item.addActionListener(this);
		m2.add(item);
		item = new JMenuItem("빨간색");
		key = KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK);
		item.setAccelerator(key);
		item.addActionListener(this);
		m2.add(item);
		item = new JMenuItem("노란색");
		key = KeyStroke.getKeyStroke(KeyEvent.VK_Y, ActionEvent.CTRL_MASK);
		item.setAccelerator(key);
		item.addActionListener(this);
		m2.add(item);
		mb.add(m1);
		mb.add(m2);
		setJMenuBar(mb);
	}

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

	public void actionPerformed(ActionEvent e) {
		JMenuItem mi = (JMenuItem) (e.getSource());

		switch (mi.getText()) {
		case "새 파일":
			System.out.println("새 파일");
			break;
		case "파일 열기":
			System.out.println("파일 열기");
			break;
		case "파란색":
			this.getContentPane().setBackground(Color.BLUE);
			break;
		case "빨간색":
			this.getContentPane().setBackground(Color.RED);
			break;
		case "노란색":
			this.getContentPane().setBackground(Color.YELLOW);
		}
	}
}

 
 
 

728x90

'💻 Programming > Java' 카테고리의 다른 글

[JAVA] 개념 정리 (3)  (0) 2023.10.19
[JAVA] 개념 정리 (1)  (2) 2023.10.15