19일 JAVA(19)
1. AWT, Swing, Android의 이벤트 처리
1) 객체의 이벤트 처리를 위임할 인터페이스나 추상클래스의 객체를 생성
- 인터페이스나 추상클래스를 상속하는 클래스를 만들고 객체를 생성
- 클래스를 만들지 않고 객체를 생성
2) 객체의 add이벤트Listener(1번에서 만든 객체)를 호출
=>객체에 이벤트가 발생하면 1번에서 만든 객체의 메소드가 호출됩니다.
2. Event
1) ActionEvent
=>버튼을 클릭하거나 메뉴를 누르거나 텍스트 필드 등에서 Enter를 눌렀을 때 발생하는 이벤트
=>ActionListener 인터페이스로 처리
=>ActionListener 인터페이스에서 actionPerformed(ActionEvent e) 메소드가 존재하고 ActionEvent가 발생하면 이 메소드가 호출됩니다.
=>ActionEvent의 메소드
- getActionCommand(): 이벤트가 발생한 객체의 텍스트가 리턴됩니다.
- getSource(): 이벤트가 발생한 객체의 해시코드가 리턴됩니다.
- getModifiers(): 이벤트가 발생했을 때 같이 누른 조합키(ALT, CTRL, SHIFT)의 값이 리턴됩니다.
2) 이벤트 라우팅
=>2개 이상의 객체의 이벤트를 하나의 객체로 처리하는 것
=>각 객체마다 이벤트 처리를 위한 객체를 갖는 것은 자원의 낭비
=>이벤트가 발생했을 때 호출되는 메소드의 매개변수는 이벤트가 발생한 객체의 정보를 리턴해주는 메소드를 소유하고 있습니다.
=>ActionEvent 의 경우는 getActionCommand() 또는 getSource()
=>이벤트를 처리하는 메소드에서 getActionCommand() 나 getSource()의 리턴값을 가지고 분기문을 만들면 됩니다.
3) ItemEvent
=>체크박스나 라디오 버튼을 누를 때 또는 콤보박스(Choice)에서 다른 항목을 선택했을 때를 처리해주는 이벤트
=>ItemListener 인터페이스를 이용해서 처리합니다.
4) TextEvent
=>TextField 나 TextArea에 문자를 입력할 때 발생하는 이벤트
=>TextListener가 이벤트를 처리하게 되고 textValueChanged(TextEvent e) 메소드가 호출됩니다.
실습) TextField 와 TextArea 를 이용한 복사, ItemEvent 도 사용
package java0115;
public class Main1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
new EventMain();
}
}
3. KeyEvent
=>키보드 이벤트
=>KeyListener 인터페이스가 처리
=>호출되는 메소드
keyPressed(KeyEvent e): 키보드가 눌러지면 호출되는 메소드
keyReleased(KeyEvent e): 키보드에서 손을 떼면 호출되는 메소드
keyTyped(KeyEvent e): keyPressed가 호출되고 난 후 누른 키보드 값이 문자이면 호출되는 메소드
keyPressed는 대소문자 구분을 하지 않지만 keyTyped 는 대소문자를 구분합니다.
=>KeyEvent의 메소드
getKeyChar(): 누른 문자 값을 리턴 - 문자 키에만 반응
getKeyCode(): 누른 키보드 값을 리턴
실습) 문자모양의 테트리스 + 간단한 총알 쏘기 (총알쏘면 위로 다 올라갈때까지 움직이지 X)
package java0115;
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyWindow extends Frame{
private static final long serialVersionUID = 1L;
public KeyWindow() {
setLayout(null);
//레이블을 생성하고 윈도우에 배치
Label lbl = new Label("@");
lbl.setBounds(10,40,30,20);
add(lbl);
Label bullet = new Label("|");
bullet.setBounds(10, 30, 30, 20);
bullet.setVisible(false);
add(bullet);
//키보드 이벤트 처리를 위한 객체 만들기
KeyListener keyListener = new KeyListener() {
//위방향키를 눌렀을때 모양을 변경하기 위하 변수 선언
//변경하고자 하는 모양만큼 배열을 생성
String [] ar= {"@","#","$","%"};
//모양을 변경하기 위한 인덱스 변수
int idx = 0;
@Override
public void keyPressed(KeyEvent e) {
System.out.println(e.getKeyCode());
int x = lbl.getX();
int y = lbl.getY();
//esc를 누르면 프로그램 종료
if(e.getKeyCode()==27) {
System.exit(0);
}else if(e.getKeyCode()==37) {
x=x-10;
}else if(e.getKeyCode()==38) {
idx=idx+1;
lbl.setText(ar[idx%ar.length]);
}else if(e.getKeyCode()==39) {
x=x+10;
}else if(e.getKeyCode()==40) {
y=y+10;
}else if(e.getKeyCode()==10) {
y=470;
}else if(e.getKeyCode()==32) {
bullet.setVisible(true);
bullet.setLocation(x+5, y-10);
int k = y;
while(true) {
k=k-10;
if(k<10) {
return;
}
try {
Thread.sleep(1000);
bullet.setLocation(x+5, k);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
lbl.setLocation(x, y);
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
};
this.addKeyListener(keyListener);
setTitle("키보드 이벤트");
setBounds(100,100,500,500);
setVisible(true);
}
}
4. MouseEvent
=>영역 내에서 들어왔다가 나가는 경우 또는 버튼을 누르거나 손을 뗐을 때 호출되는 이벤트
=>MouseListener가 처리합니다.
=>Listener의 메소드
mouseClicked(MouseEvent e): 마우스를 클릭했을 때 호출
mouseEntered(MouseEvent e): 마우스 커서가 컴포넌트 영역에 들어오면 호출
mouseExited(MouseEvent e): 마우스 커서가 컴포넌트 영역에서 벗어나면 호출
mousePressed(MouseEvent e): 마우스 버튼이 눌러지면 호출
mouseReleased(MouseEvent e): 마우스 버튼이 눌러졌다 띄어지면 호출
=>MouseEvent의 메소드
getX(): 누른 X좌표
getY(): 누른 Y좌표
getPoint(): x와 y좌표 같이
5 .MouseMotionEvent
=>마우스를 움직이면 호출되는 이벤트
=>MouseMotionListener 인터페이스를 이용해서 처리
=>메소드
mouseDragged(MouseEvent e): 마우스 버튼이 눌러진 상태로 이동하면 호출
mouseMoved(MouseEvent e): 마우스를 이동하면 호출
6 .WindowEvent
=>Frame에 변화가 생겼을 때 호출되는 이벤트
=>WindowListener 인터페이스를 이용해서 처리
=>메소드
windowOpened(WindowEvent e): 윈도우가 열릴 때
windowClosing(WindowEvent e): 윈도우가 닫힐 때 - 종료 버튼을 누를 때
windowClosed(WindowEvent e): 시스템 닫힌 후 - 종료 되고 난 후
windowActivated(WindowEvent e): 윈도우가 활성화 되었을 때
windowDeactivated(WindowEvent e): 윈도우가 비 활성화 되었을 때
windowIconified(WindowEvent e): 윈도우가 아이콘화 되었을 때
windowDeiconfied(WindowEvent e): 윈도우가 최소화 상태에서 원래대로 되돌아 올 때
실습) 마우스 옆에 label ("@")를 붙이고 클릭하면 마우스의 좌표 출력
package java0115;
public class Main3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
new MouseWindow();
}
}
package java0115;
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class MouseWindow extends Frame {
public MouseWindow() {
setLayout(null);
Label pos = new Label("좌표 X:000 Y:000");
pos.setBounds(200,100,200,30);
add(pos);
Label pointer = new Label("@");
pointer.setBounds(0,0,30,30);
add(pointer);
MouseListener mouseListener = new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
//정수와 문자열을 가지고 서식 문자열 만들기
String msg = String.format("좌표 X:%d Y:%3d",x,y);
pos.setText(msg);
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
};
MouseMotionListener motionListener = new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseMoved(MouseEvent e) {
//레이블의 위치를 마우스의 좌표로 변경
pointer.setLocation(e.getX()+5, e.getY()-10);
}
};
WindowListener windowListener = new WindowListener() {
@Override
public void windowActivated(WindowEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void windowClosed(WindowEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void windowClosing(WindowEvent arg0) {
System.exit(0);
}
@Override
public void windowDeactivated(WindowEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void windowOpened(WindowEvent arg0) {
// TODO Auto-generated method stub
}
};
this.addWindowListener(windowListener);
this.addMouseMotionListener(motionListener);
this.addMouseListener(mouseListener);
setTitle("마우스 이벤트");
setBounds(100,100, 600,600);
setVisible(true);
}
}
7. Adapter Class
=>이벤트 처리를 위한 클래스
=>Listener 인터페이스를 이용해서 이벤트를 처리를 하는데 인터페이스는 소유하고 있는 메소드가 전부 추상 메소드여서 인터페이스를 implements하게되면 모든 메소드를 재정의해야 합니다.
=>이벤트 처리 메소드가 2개 이상인 인터페이스를 미리 구현한 클래스를 제공하는데 이러한 클래스를 Adapter Class 라고 합니다.
=>Adapter Class를 이용해서 이벤트를 처리하게 되면 필요한 메소드만 재정의해서 처리할 수 있습니다.
8. Swing 과 AWT
=>Swing은 Java의 자원을 가지고 GUI 프로그래밍을 하는 반면에 AWT는 운영체제의 자원을 사용합니다.
=>Swing이 AWT 보다는 가볍습니다.
=>Swing이 프로그래밍이 조금 더 어렵습니다.
1) JFrame
=>Swing의 윈도우 클래스
=>종료기능 구현은 setDefaultCloseOperation(EXIT_ON_CLOSE)를 호출하면 됩니다.
=>화면 출력방법이나 사용방법은 AWT의 Frame과 거의 동일합니다.
2) JPanel
=>여러 개의 Component들을 묶어서 사용하기 위한 Container
=>기본 Layout이 FlowLayout(순서대로 위에서부터 배치)
3) JScrollPane
=>부모 화면보다 자식의 화면이 더 큰 경우에 부모 보다 큰 나머지 부분은 출력할 수 없습니다.
=>이런 경우에는 JScrollPane 위에 자식의 화면을 배치하고 JScrollPane을 부모 화면에 배치하면 ScrollBar가 생겨서 부모 보다 큰 나머지 부분을 출력할 수 있게 됩니다.
=>JScrollPane 위에는 하나의 Component 만 배치가 가능하므로 여러 개를 배치하고자 할 때는 JPanel에 배치를 하고 JPanel을 JScrollPane 위에 배치해야 합니다.
4) Swing의 컴포넌트에 추가된 기능
=>border(경계선) 설정 가능
=>tooltip 가능
5) JLabel
=>텍스트나 이미지를 출력하기 위한 컴포넌트
=>생성자에서 Icon 을 설정해서 대입하면 이미지가 출력됩니다.
- Icon 객체를 이미지 파일로 생성하는 방법
Icon 변수명 = new ImageIcon("이미지 파일의 경로")
- 파일의 경로
=>절대 경로: 루트로부터의 경로
c:\image\test.png
=>상대 경로: 현재 위치로부터의 경로
./:현재 디렉토리
../: 상위 디렉토리
현재 디렉토리 경로는 ./를 생략해도 됩니다.
package java0115;
public class Main4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
new SwingWindow();
}
}
package java0115;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class SwingWindow extends JFrame{
private static final long serialVersionUTD = 1L;
public SwingWindow() {
JPanel p = new JPanel();
//상대 경로를 이용해서 이미지 출력
Icon icon = new ImageIcon("C:\\Users\\K.W.S\\Pictures\\Saved Pictures\\10.png");
JLabel lbl = new JLabel(icon);
lbl.setToolTipText("안녕하세요 레이블입니다.");
p.add(lbl);
add(p);
System.out.println(System.getProperty("uer.dir"));
setTitle("Swing의 Frame");
setBounds(10,10,400,400);
setVisible(true);
//종료버튼의 이벤트 처리
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
console 창의 값은 null
실습) 화면 바뀌는거 만들기 (애니메이션 만들기)
package java0115;
public class Main5 {
public static void main(String[] args) {
new AnimationWindow();
}
}
6) 버튼
- JButton: 일반적인 버튼
- JToggleButton: 2가지 상태를 갖는 버튼
- JRadioButton: 라디오 버튼
- JCheckBox: 체크박스
=>만드는 방법은 각각 다르지만 사용법은 동일
=>RadioButton 의 경우는 ButtonGroup 클래스의 객체를 생성한 후 add를 이용해서 묶어주면 하나의 그룹이 됩니다.
=>라디오 버튼이나 체크박스는 배열로 만드는 것이 좋습니다.
어떤 버튼이 체크되었는지 확인하기가 편리합니다.
실습) JRadioButton 사용과 JCheckBox 배열로 사용하기, 출력하기
package java0115;
public class Main6 {
public static void main(String[] args) {
new ButtonWindow();
}
}
package java0115;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class ButtonWindow extends JFrame{
private static final long serialVersionUID = 1L;
public ButtonWindow() {
JPanel p = new JPanel();
JRadioButton man = new JRadioButton("남자",true);
JRadioButton woman = new JRadioButton("여자");
ButtonGroup gender = new ButtonGroup();
gender.add(man);
gender.add(woman);
p.add(man);
p.add(woman);
// JCheckBox ch1 = new JCheckBox("운동");
// JCheckBox ch2 = new JCheckBox("독서");
// JCheckBox ch3 = new JCheckBox("게임");
//
// p.add(ch1);
// p.add(ch2);
// p.add(ch3);
//
JCheckBox [] ch = new JCheckBox[3];
ch[0]= new JCheckBox("운동");
ch[1]= new JCheckBox("독서");
ch[2]= new JCheckBox("게임");
for(JCheckBox imsi : ch) {
p.add(imsi);
}
JButton btn = new JButton("확인");
p.add(btn);
add(p);
setTitle("버튼 윈도우");
setBounds(50,50,300,300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String hobby= "";
// if(ch1.isSelected()==true) {
// hobby=hobby+ch1.getText();
// }
// if(ch2.isSelected()==true) {
// hobby=hobby+ch2.getText();
// }
// if(ch3.isSelected()==true) {
// hobby=hobby+ch3.getText();
// }
for(JCheckBox imsi :ch) {
if(imsi.isSelected()==true) {
hobby = hobby + imsi.getText()+" ";
}
}
System.out.println(("취미는: "+hobby));
}
};
btn.addActionListener(actionListener);
}
}