---------학교에서 배운 내용(개인적으로 공부한 내용), 여기서부터 이해가 필요한거 같아서 정리해서 올립니다---------
<<<<<<<<<<<<<<JAVA의 이벤트 처리>>>>>>>>>>>>>>>>>>>>>
이벤트(event) : 어떤 동작(마우스로 버튼을 클릭하는 것 등)에 의하여 발생한다. 이벤트가 발생하면 해당 컴포넌트가 이벤트 객체를 생성한다.
이벤트 객체(event object) : 이벤트에 대한 여러가지 정보를 가지고 있다.
이벤트 소스(event source) : 이벤트를 발생시킨 컴포넌트를 부르는 말이다.
이벤트 리스너(event listen) : 발생된 이벤트 객체에 반응하여서 이벤트를 처리한는 객체
* ActionEvent, MouseEvent 많이 쓴다
* 사용자가 버튼을 클릭하는 경우에 버튼 컴포넌트가 이벤트 소그가 되어 이벤트 객체를 생성한다.
이벤트 처리의 과정
1. 이벤트를 발생하는 컴포넌트를 생성하여야 한다.
2. 이벤트 리스너 클래스를 작성한다.
3. 이벤트 리스너를 이벤트 소스에 등록한다.
내부 클래스를 사용하는 방법 : 예제로 설명
예제) 버튼이 눌러지면 버튼의 텍스트를 변경하는 프로그램을 작성하기
MyFrameTest6.java
package GUI;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
class MyFrame8 extends JFrame {
// JButton 멤버 변수로 선언.
// 생성자와 actionPerformed() 메서드에서 사용하기 때문에 멤버 변수로 선언하였다.
private JButton button;
public MyFrame8() {
this.setSize(200, 100);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle("버튼 이벤트 예제");
JPanel panel = new JPanel();
button = new JButton("버튼을 누르세요.");
button.addActionListener(new MyListener()); // 이벤트 리스너 등록
panel.add(button);
this.add(panel);
this.setVisible(true);
}
클래스에서 이벤트를 처리하는 방법 : 예제로 설명
예제) 내부 클래스로 정의하는 방법 외에 위의 예제에서 MyFrame8 클래스가 jFrame을 상속받으면서 동시에 ActionListener 인터페이스도 구현하는 방법이다.
MyFrameTest7.java
package GUI;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
class MyFrame8 extends JFrame implements ActionListener{
// JButton 멤버 변수로 선언.
// 생성자와 actionPerformed() 메서드에서 사용하기 때문에 멤버 변수로 선언하였다.
private JButton button;
public MyFrame9() {
this.setSize(200, 100);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle("버튼 이벤트 예제2");
JPanel panel = new JPanel();
button = new JButton("버튼을 누르세요.");
button.addActionListener(this); // 현재 객체를 리스너로 등록
panel.add(button);
this.add(panel);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button) { // getSource() : 이벤트 소스를 반환하는 메서드
button.setText("버튼이 눌러졌습니다.");
}
}
}
public class MyFrameTest7 {
public static void main(String[] args) {
MyFrame9 f = new MyFrame9();
}
}
- 내부 클래스 : 다른 클래스 안에 위치하는 클래스로, 내부 클래스에서 외부 클래스의 멤버 변수들을 자유롭게 사용 가능.
내부클래스의 장점
1. 내부클래스에서 외부클래스의 멤버들을 쉽게 접근할 수 있따.
2. 코드의 복잡성을 줄일 수 있다(캡슐화)
내부클래스는 클래스 내에 선언된 클래스로, 두 클래스가 서로 긴밀한 관계가 있을 때 내부클래스를 사용한다.
한 클래스를 다른 클래스의 내부클래스로 선언하면 두 클래스 멤버들 간에 서로 쉽게 접근할 수 있고, 외부에는 불필요한 클래스를 감춰서 코드의 복잡성을 줄일 수 있다는 장점이 있다.
내부클래스의 종류와 특징
인스턴스 클래스(instance class) = 외부클래스의 멤버변수 선언위치에 선언하며, 외부클래스의 인스턴스 멤버처럼 다뤄진다. 주로 외부클래스의 인턴스멤버들과 관련된 작업에 사용될 목적으로 선언된다.
스타틱 클래스(static class) = 외부클래스의 멤버변수 선언 위치에 선언하며 외부클래스의 static멤버처럼 다뤄진다.
주로 외부클래스의 static멤버, 특히 static메서드에서 사용될 목적으로 선언된다.
지역클래스(local class) = 외부클래스의 메서드나 초기화블럭 안에 선언하며, 선언된 영역내부에서만 사용될 수있다.
익명클래스(anonymous class) = 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용)
---------------------------내부클래스의 종류는 변수의 선언 위치에 따른 종류와 같다.---------------------------
내부클래스의 선언방법
class Outer{
class InstanceInner { } // 인스턴스클래스
static class StaticInner { } // 스타틱클래스
void method1(){
class LocalInner { } // 지역클래스
}
}
- 익명 클래스 : 클래스의 선언과 객체의 생성을 동시에 하기 때문에 단 한 번만 사용될 수 있고, 오직 하나의 객체만을 생성할 수 있는 일회용 클래스이다.
이름이 없기 때문에 생성자도 가질 수 없으며, 부모 클래스의 이름이나 구현하고자 하는 인터페이스의 이름을 사용해서 정의하기 때문에 하나의 클래스로 상속받는 동시에 인터페이스를 구현하거나 둘 이상의 인터페이스를 구현할 수 없다.
오로지 단 하나의 클래스를 상속받거나 단 하나의 인터페이스 만을 구현할 수 있다.
예시)
package test;
class test{
Object iv = new Object() { void method(){ } }; // 익명클래스
static Object cv = new Object() { }}; // 익명클래스
void myMethod(){
Object iv = new Object() { void method() { }}; // 익명클래스
}
}
익명클레스는 이름이 없기 때문에 "외부클래스명$숫자.class."의 형식으로 클래스 파일명이 결정된다.
코드를 컴파일 하려면 main을 넣어야 한다. test.class 외에 test$1.class, test$2class, test$3class라는
3개의 클래스 파일이 생성된다.
어댑터 클래스
keyEvent 와 keyListener
-component.setFocusable(true);
-component.requestFocus();
keyTyped()
MouseEvent, MouseListener, MouseMotionListener, MouseWheelListener
키
유니코드키
유니코드가 아닌 키
가상 키
<이벤트 처리 예제>
예제 10-1. 버튼을 클릭할 때 발생하는 Action 이벤트를 처리할 MyActionListener 클래스를 독립클래스로 작성하고 클릭할 때마다 버튼 문자열이 "Action"과 "액션"으로 번갈아 변하도록 하라.
※ 독립클래스로 Action 이벤트의 리스너 작성
package test10;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
/*class MyAction implements ActionListener{
@Override
public void actionPerformed(ActionEvent arg0) {
JButton b=(JButton)arg0.getSource(); //이벤트 발생한 소스를 얻는다
if(b.getText().equals("Action"))
b.setText("액션");
else b.setText("Action");
}
}*/
public class EventTest01 extends JFrame {
JButton btn;
EventTest01() {
setTitle("이벤트처리");
setSize(300, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c=getContentPane();
c.setLayout(new FlowLayout());
btn=new JButton("Action");
c.add(btn);
setVisible(true);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
JButton b=(JButton)arg0.getSource(); //이벤트 발생한 소스를 얻는다
if(b.getText().equals("Action"))
b.setText("액션");
else b.setText("Action");
}
});
}
public static void main(String[] args) {
new EventTest01();
}
/*class MyAction implements ActionListener{
@Override
public void actionPerformed(ActionEvent arg0) {
JButton b=(JButton)arg0.getSource(); //이벤트 발생한 소스를 얻는다
if(b.getText().equals("Action"))
b.setText("액션");
else b.setText("Action");*/
}
예제 10-2. 10-1과 같은 내용을 내부 클래스로 이벤트 리스너를 만들어보자.
※ 내부클래스로 Action 이벤트의 리스너 작성
package test10;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
//class MyAction implements ActionListener{
// private JTextField tf1, tf2;
// private JLabel la;
// MyAction(JTextField tf1, JTextField tf2, JLabel la){
// this.tf1=tf1;
// this.tf2=tf2;
// this.la=la;
// }
// @Override
// public void actionPerformed(ActionEvent arg0) {
// //JButton b=(JButton)arg0.getSource();
// int num1=Integer.parseInt(tf1.getText());
// int num2=Integer.parseInt(tf2.getText());
// la.setText((num1+num2)+" ");
//
// }
//
//}
public class EventTest02 extends JFrame {
JTextField tf1, tf2;
JLabel la; //값이 안바뀌어서 만들필요 ㄴㄴ
JButton btn;
EventTest02() {
setTitle("이벤트처리");
setSize(200, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c=getContentPane();
c.setLayout(new GridLayout(4,1));
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
tf1 = new JTextField(10);
p1.add(new JLabel("숫자1: "));
p1.add(tf1);
tf2 = new JTextField(10);
p2.add(new JLabel("숫자2: "));
p2.add(tf2);
la=new JLabel("처리결과");
p3.add(new JLabel("계산결과"));
p3.add(la);
btn=new JButton("더하기");
c.add(p1);
c.add(p2);
c.add(btn);
c.add(p3);
setVisible(true);
btn.addActionListener(new MyAction());
}
public static void main(String[] args) {
new EventTest02();
}
class MyAction implements ActionListener{
// private JTextField tf1, tf2;
// private JLabel la;
// MyAction(JTextField tf1, JTextField tf2, JLabel la){
// this.tf1=tf1;
// this.tf2=tf2;
// this.la=la;
// }
@Override
public void actionPerformed(ActionEvent arg0) {
//JButton b=(JButton)arg0.getSource();
int num1=Integer.parseInt(tf1.getText());
int num2=Integer.parseInt(tf2.getText());
la.setText((num1+num2)+" ");
}
}
}
예제 10-3. 10-1, 10-2와 같은 내용을 내부 클래스로 이벤트 리스너를 만들어보자.
※ 익명클래스로 Action 이벤트의 리스너 작성
대기중
예제 10-4. 컨탠트팬의 아무 위치에 마우스버튼을 누르면 마우스 포인트가 있는 위치로 "hello"문자열을 옮기는 스윙 응용프로그램을 작성하라. #마우스이벤트연습

package test10;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class MouseTest extends JFrame implements MouseListener{
JLabel la;
Container c;
MouseTest(){
setTitle("Mouse 이벤트예제");
setSize(300, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
c=getContentPane();
c.setLayout(null);
la=new JLabel("Hello");
la.setSize(50,20);
la.setLocation(10, 10);
c.add(la);
setVisible(true);
c.addMouseListener(this);
}
public static void main(String[] args) {
new MouseTest();
}
@Override
public void mouseClicked(MouseEvent arg0) {
// 좌표가 없어도 됨
// c.setBackground(Color.RED);
}
@Override
public void mouseEntered(MouseEvent e) {
// 마우스가 화면 안에 들어올 때
// c.setBackground(Color.BLACK);
}
@Override
public void mouseExited(MouseEvent e) {
// 마우스가 화면 밖에 나갈 때
// c.setBackground(Color.YELLOW);
}
@Override
public void mousePressed(MouseEvent e) {
int x=e.getX();
int y=e.getY();
la.setLocation(x, y); //클릭하는 위치
}
@Override
public void mouseReleased(MouseEvent e) {
// 안쓴다고 지우면 에러납니다.
// 키를 떼는 순간
}
}
예제 10-5. MouseAdapter를 이용하여 예제 10-4를 수정하라.
package test10;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class MouseAdapterTest extends JFrame {
JLabel la;
MouseAdapterTest(){
setTitle("마우스어댑터테스트");
setSize(300, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c=getContentPane();
c.setLayout(null);
la=new JLabel("Hello");
la.setBounds(10,10,50,20);
c.add(la);
setVisible(true);
c.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int x=e.getX();
int y=e.getY();
la.setLocation(x, y);
}
});
}
public static void main(String[] args) {
new MouseAdapterTest();
}
}
예제 10-6. 입력된 키의 키코드, 유니코드, 키의 이름 문자열을 읽는 코드.
※ keyEvent와 keytListener의 활용


package test10;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class KeyEventTest01 extends JFrame implements KeyListener{
private JLabel[] keyMessage;
KeyEventTest01(){
setTitle("keyListener 예제");
setSize(300, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c=getContentPane();
c.setLayout(new FlowLayout());
c.addKeyListener(this);
keyMessage=new JLabel[3];
keyMessage[0]=new JLabel("getKeyCode");
keyMessage[1]=new JLabel("getKeyChar");
keyMessage[2]=new JLabel("getKeyText");
for(int i=0; i<keyMessage.length; i++) {
c.add(keyMessage[i]);
keyMessage[i].setOpaque(true); //레이블 배경은 기본이 투명. 텍스트는 아님!
keyMessage[i].setBackground(Color.YELLOW);
}
setVisible(true);
c.setFocusable(true); //포커스 받을 수 있게 함
c.requestFocus();
}
public static void main(String[] args) {
new KeyEventTest01();
}
@Override
public void keyPressed(KeyEvent arg0) {
//눌러졌을때 키코드를 얻음
//1번 (작동순서)
int keyCode=arg0.getKeyCode();
int keyChar=arg0.getKeyChar();
String keyStr=arg0.getKeyText(keyCode);
keyMessage[0].setText(keyCode+"");
keyMessage[1].setText(keyChar+"");
keyMessage[2].setText(keyStr+"");
}
@Override
public void keyReleased(KeyEvent arg0) {
//3번
// int keyCode=arg0.getKeyCode();
// int keyChar=arg0.getKeyChar();
// String keyStr=arg0.getKeyText(keyCode);
// keyMessage[0].setText(keyCode+"");
// keyMessage[1].setText(keyChar+"");
// keyMessage[2].setText(keyStr+"");
//
}
@Override
public void keyTyped(KeyEvent arg0) {
//2번.유니코드만 받습니다.
// int keyCode=arg0.getKeyCode();
// int keyChar=arg0.getKeyChar();
// //String keyStr=arg0.getKeyText(keyCode);
// keyMessage[0].setText(keyCode+"");
// keyMessage[1].setText(keyChar+"");
// keyMessage[2].setText("");
//
}
}
예제 10-7. 다음 그림과 같이 <F1> 키를 입력받으면 콘텐트팬의 배경을 초록색으로, % 키를 입력받으면 노란색으로 변경하는 응용프로그램을 만들어라.
※ 사용자가 키를 입력하면 입력된 키의 이름 문자열을 화면에 출력한다. %키는 shift 키 입력 후 5를 입력한 경우로서 최종적으로 입력된 키는 5이므로 오른쪽 화면에 5키가 입력되었음이라고 출력되어 있다. f1키를 받기 위해 KeyEvent의 getKeycode()메소드를 이용하여야 하며, % 키는 getKeyChar() 메소드를 이용하면 된다.
예제 10-8. 상,하,좌,우 키를 이용하여 "Hello" 문자열을 움직이는 응용프로그램을 작성하라.



※ "Hello" 문자열은 JLabel 컴포넌트로 만들어 컨텐트팬에 부착하고 상,하, 좌,우 키를 움직이면 키 방향으로 한 번에 10픽셀씩 움직인다 이를 위해 컨텐트팬의 배치관리자를 삭제하여야 한다. "Hello" 문자열을 초기에 (50,50) 위치에 출력하라.
package test10;
import java.awt.Container;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class p1008 extends JFrame{
JLabel la;
int x=50, y=50;
p1008(){
setTitle("10장 8번 예제");
setSize(300, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c=getContentPane();
c.setLayout(null);
la=new JLabel("Hello");
la.setBounds(x,y,30,20);
c.add(la);
c.setFocusable(true);
c.requestFocus();
setVisible(true);
c.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
switch((int) e.getKeyCode()) {
case KeyEvent.VK_UP:
if(y-10<0)
y=0;
else
y-=10;
break;
case KeyEvent.VK_DOWN:
if(y+10>c.getHeight()-20)
y=c.getHeight()-20;
else
y+=10;
break;
case KeyEvent.VK_LEFT:
if(x-10<0)
x=0;
else
x-=10;
break;
case KeyEvent.VK_RIGHT:
if(x+10>c.getWidth()-30)
x=c.getWidth()-30;
else
x+=10;
}
la.setLocation(x, y);
//이미 있는 위치 옮기는 것은 repaint가 필요없음
}
});
}
public static void main(String[] args) {
new p1008();
}
}
예제 10-9. 입력된 키의 키코드, 유니코드, 키의 이름 문자열을 읽는 코드.


※ keyEvent와 keytListener의 활용
package test10;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class MouseEventTest02 extends JFrame{
JLabel la;
Container c;
MouseEventTest02(){
setTitle("10-9");
setSize(300, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
c=getContentPane();
c.setLayout(new FlowLayout());
la=new JLabel("No Mouse Event"); //메모리 할당
c.add(la);
setVisible(true);
MyMouseListener l=new MyMouseListener();
c.addMouseListener(l);
c.addMouseMotionListener(l);
}
public static void main(String[] args) {
new MouseEventTest02();
}
class MyMouseListener implements MouseListener,MouseMotionListener {
@Override
public void mouseDragged(MouseEvent arg0) {
la.setText("mouseDragged("+arg0.getX()+","+arg0.getY()+")");
}
@Override
public void mouseMoved(MouseEvent arg0) {
la.setText("mouseMoved("+arg0.getX()+","+arg0.getY()+")");
}
@Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent arg0) {
c.setBackground(Color.CYAN);
}
@Override
public void mouseExited(MouseEvent arg0) {
c.setBackground(Color.MAGENTA);
}
@Override
public void mousePressed(MouseEvent arg0) {
la.setText("mousePressed("+arg0.getX()+","+arg0.getY()+")");
}
@Override
public void mouseReleased(MouseEvent arg0) {
la.setText("mouseReleased("+arg0.getX()+","+arg0.getY()+")");
}
}
}'명품자바프로그래밍' 카테고리의 다른 글
| 명품 JAVA programming 11장 (0) | 2021.09.30 |
|---|---|
| 명품 JAVA programming 9장 (0) | 2021.09.29 |
| 명품 JAVA programming 7장 (0) | 2021.09.28 |
| 명품 JAVA programming 6장 (0) | 2021.09.28 |
| 명품 JAVA programming 5장 (0) | 2021.09.28 |