◆ Java, swing, Android의 view의 이벤트 처리형식
1. 처리할 이벤트 리스너(인터페이스=프러토콜=상수와 메소드 이름만 가진 개체)를 Implements 한 클래스를 생성하고 메소드를 재정의.
->★메소드 안의 매개변수에 이벤트에 대한 정보가 전달됩니다.
여기서 메소드는 계속 써먹을 건가 아닌가를 생각해보아야 한다. |
딱 한번만 쓰는 경우, 어노니먼스 |
여러 번 쓰는 경우, 임플리먼츠된 클래스 생성 |
//상속 받는 클래스의 인스턴스를 만드는 방법 ActionListener(이거슨 자료형) a = new ActionListener(){ 메소드{ 내용(label - 글자 바꾸기 color - 색깔 바꾸기) } }; //연결 btn.addActionListener(a); | 이벤트 리스너를 임플리먼츠 한 클래스를 생성하고 메소드를 재정의. ActionListener a = new ActionListener(); |
|
클래스 |
메소드 |
마우스 클릭 때 주는 정보=마우스 이벤트 키보드 클릭 때 주는 정보=키보드 이벤트 의 클래스가 존재. |
-> 정보를 전달 |
정보를 전달 받아 가지고 있음. |
따라서 메소드 안의 매개변수를 꼭 확인해볼 필요가 있다. |
2. 이벤트를 사용할 컴포넌트에 add이벤트Listener(1번의 인스턴스);
ActionListener |
- 버튼 클릭 - 체크박스 클릭 - 리스트 클릭 - 텍스트 필드에서 엔터를 눌렀을 때 이벤트를 처리해주는 리스너 (절대 외우지 말고 검색하면 나옴...어디서 검색?) |
많이 하는 것들 |
문자열->숫자 |
숫자->문자열 |
Integer.parseInt("문자열") Double.parseDouble("문자열") |
1. 10+"" -> 자동으로 문자열이 된다. 2. String.format("%d", 숫자) - 출력이 아니라 우리한테 값을 주는 것. |
익명 클래스 만들기 : 클래스 없이 인스턴스를 만드는 것(anonymouse) |
클래스나 인터페이스 이름 ++ 변수명 = new ++ 클래나 인터페이스이름(){메소드} |
실습해보기 |
더하기 계산기(버튼 눌러서 숫자 들어가고 결과 출력) 만들기 |
1. TextListener
- 텍스트필드나 텍스트 에러리어에서 키보드를 눌러서 글자가 변경되면 발생하는 이벤트를 처리하는 인터페이스
package eventHandling;
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
public class Aclass extends Frame {
//생성자
public Aclass() {
//위치&크기
setBounds(200,200,320,600);
//타이틀
setTitle("Aclass_텍스트 이벤트");
//여러 개를 배치하기 위해서 패널을 설치
Panel p = new Panel();
//5칸 텍스트 필드 생성 - 패널에 설치
TextField tf1 = new TextField(5);
p.add(tf1);
//+ 라벨 생성 - 패널에 설치
Label plus = new Label("+");
p.add(plus);
//5칸 텍스트 필드 생성 - 패널에 설치
TextField tf2 = new TextField(5);
p.add(tf2);
//= 라벨 생성 - 패널에 설치
Label assign = new Label("=");
p.add(assign);
//결과가 나올 6칸 텍스트 필드 생성 - 패널에 설치
TextField result = new TextField(6);
p.add(result);
//결과 출력 이벤트가 들어갈 버튼 생성 - 패널에 설치
//버튼 글자가 깨지면 - ms949로 바꾸기 - 윈도우 프로그램이라서 그런 것임.
Button btn = new Button("계산");
p.add(btn);
//**--Event-Start--**//
//ActionListener 인터페이스의 anonymous class생성
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//첫번째 와 두번째 텍스트 필드의 내용 가져오기
String n1 = tf1.getText();
String n2 = tf2.getText();
//정수로 바꾸어서 결과를 만들기
int r = Integer.parseInt(n1) + Integer.parseInt(n2);
//결과를 result 텍스트 필드에 넣기
String rr = String.format("%d",r); //result.setText(r+""); -이런 방법도 있다.
result.setText(rr);
}
};
btn.addActionListener(listener); //- 버튼을 클릭하면 이벤트를 실행하겠다는 것.
//**--Event-End--**//
//글자 출력 - 부착
Label lblPw = new Label("비밀번호");
p.add(lblPw);
//텍스트 필드 생성 - 부착
TextField pw = new TextField(15);
p.add(pw);
//텍스트 입력에 따라 결과를 출력하기 위함 - 부착
Label pwResult = new Label();
p.add(pwResult);
//**--Event-Start--**//
//텍스트 피드의 내용이 변경 될 때를 처리할 수 있는 인터페이스의 인스턴스 생성
TextListener t1 = new TextListener() {
@Override
public void textValueChanged(TextEvent arg0) {
//텍스트 필드의 내용 받아오기
String password = pw.getText();
//각 문자 종류별로 개수 세기
//개수를 저장할 변수 만들기
int dae = 0; //대문자
int so = 0; //소문자
int num = 0; //숫자
int tc = 0; //특수문자
//password의 모든 글자를 순회(조사)
for(int i=0; i<password.length(); i++) {
//모든 문자 수집
char ch = password.charAt(i);
//대문자 인지 확인: A-Z
if(ch>='A' && ch<= 'Z') {
dae = dae + 1;
}
//소문자 인지 확인: a-z
else if(ch>='a' && ch<='z') {
so = so + 1;
}
//숫자 인지 확인: 0-9 - 입력한 숫자가 문자이기 때문에 문자로 인지를 해야합니다.
else if(ch>='0' && ch<='9') {
num = num + 1;
}
//특수문자 인지 확인: 영어대소문자, 숫자가 아닌 것.
else {
tc = tc + 1;
}
}
//각 문자가 1개 이상이어야 함
//4개 중에 한개도 0이 없으면
if(dae*so*num*tc>0) {
pwResult.setForeground(Color.GREEN);
pwResult.setText("사용 가능한 비밀번호");
}else {
pwResult.setForeground(Color.RED);
pwResult.setText("너무 약한 비밀번호 입니다.");
}
}
};
pw.addTextListener(t1); //이 이벤트를 어느곳에 적용시킬것인지.이벤트처리기(이벤트처리기 이름); - 이벤트를 필요한 곳에 부착
//**--Event-End--**//
//프레임에 패널을 설치
add(p);
//화면 출력
setVisible(true);
}
}
2. KeyListener
- 키보드를 눌렀을 때 처리를 위한 인터페이스
- 이벤트처리 메소드에 KeyEvent가 전달되는데 이 매개변수의 getKeychar()를 호출하면 누른 문자가 리턴되는데 대수문자 구분을 하지만 문자 이외의 키에는 반응을 하지 않음
- getKeyCode()는 누른 키보드의 코드 값을 리턴하는데 대소문자 구분을 하지 못합니다. 대신 문자 이외의 키에도 반응을 합니다. KeyEvent의 field로 값이 리턴됩니다.
package eventHandling;
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Bclass extends Frame {
public Bclass() {
setBounds(200, 200, 600, 600);
setTitle("Bclass_키보드 이벤트");
setLayout(null);
Label lb1 = new Label("@");
lb1.setBounds(10, 40, 50, 50);
add(lb1);
KeyListener key = new KeyListener() {
// 키보드를 눌렀을 때
@Override
public void keyPressed(KeyEvent e) {
int x = lb1.getLocation().x;
int y = lb1.getLocation().y;
// 열거형은 switch를 못 씀
if (e.getKeyCode() == e.VK_LEFT) {
x = x - 10;
}
if (e.getKeyCode() == e.VK_RIGHT) {
x = x + 10;
}
if (e.getKeyCode() == e.VK_UP) {
y = y - 10;
}
if (e.getKeyCode() == e.VK_DOWN) {
y = y + 10;
}
// @ 위치 바꾸기 //y값이 위로 못 움직이게 하려면 -한 만큼 아래에서 + 해주면 된다.
lb1.setLocation(x, y);
// Modifiers는 같이 누른 조합키 값을 리턴
if (e.getModifiers() == KeyEvent.ALT_MASK && e.getKeyCode() == KeyEvent.VK_F1) {
System.exit(0);
}
if(e.getKeyCode() == KeyEvent.VK_SPACE){
Label lb2 = new Label("+");
lb2.setBounds(lb1.getLocation().x,lb1.getLocation().y-30, 30,30);
add(lb2);
Thread th = new Thread() {
public void run() {
try {
while(true) {
Thread.sleep(50);
int x = lb2.getLocation().x;
int y = lb2.getLocation().y;
lb2.setLocation(x,y-5);
if(y < 100) {break;}
}
lb2.setVisible(false);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
th.start();
}
}
// 키보드에서 손을 뗐을 때
@Override
public void keyReleased(KeyEvent e) {
}
// 문자 키를 눌렀을 때
@Override
public void keyTyped(KeyEvent e) {
}
};
addKeyListener(key); //frame에 키보드 이벤트 연결
setVisible(true);
}
}
3. MouseListener
마우스 포인터가 영역 내에 들어오거나 / 영역에서 벗어날 때 / 클릭했을 때 / 누르고 있을 때 / 손을 땠을 때 처리를 위한 리스너
->메소드의 매개변수는 MouseEvent 인스턴스인데 이 인스턴스의 메소드를 호출하면 마우스 포인터의 위치와 동작을 알아낼 수 있습니다.
4. MouseMotionListener
마우스를 움질일 때 처리를 위한 리스너
->버튼을 누르고 움직일 때와 그냥 움직일 때 처리를 위한 메소드가 만들어져 있습니다.
->메소드의 매개변수는 똑같이 MouseEvent입니다.
5. WindowListener
윈도우를 조작하기 위한 처리를 할 때 사용하는 리스너
6. Adapter Class
Listener 인터페이스 중에서 메소드를 2개 이상 가진 인터페이스를 구현한 클래스
메소드의 내용은 아무것도 없습니다.
장점: Listener 인터페이스를 이용하면 모든 메소드를 재정의해야 하지만 Adapter클래스를 이용하면 필요한 메소드만 재정의 하면 됩니다.
단점: 인터페이스를 이용하면 코드 센스 기능을 이용해서 메소드를 쉽게 만들 수 있지만 클래스를 이용하면 메소드를 직접 만들어야 해서 코딩 할 때는 오히려 불편합니다.
//윈도우 조작을 위한 이벤트를 처리하기 위한 리스너
WindowListener wl = new WindowListener(){
@Override
public void windowActivated(WindowEvent arg0) {
}
@Override
public void windowClosed(WindowEvent arg0) {
}
//종료 버튼을 누를 때 호출되는 메소드
@Override
public void windowClosing(WindowEvent arg0) {
System.exit(0);
}
@Override
public void windowDeactivated(WindowEvent arg0) {
}
@Override
public void windowDeiconified(WindowEvent arg0) {
}
@Override
public void windowIconified(WindowEvent arg0) {
}
@Override
public void windowOpened(WindowEvent arg0) {
}
};
//frame에 윈도우 이벤트 부착
addWindowListener(wl);
//윈도우 조작을 위한 이벤트를 처리하기 위한 리스너
WindowAdapter wl = new WindowAdapter(){
//종료 버튼을 누를 때 호출되는 메소드
@Override
public void windowClosing(WindowEvent arg0) {
System.exit(0);
}
};
//frame에 윈도우 이벤트 부착
addWindowListener(wl);