IT/JAVA (17.12.18~)

19일 JAVA(19)

만두토끼 2018. 1. 16. 09:30

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();

}

}



package java0115;

import java.awt.Button;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

//윈도우 클래스
public class EventMain extends Frame{
private static final long serialVersionUTD = 1L;
public EventMain() {
//윈도우가 화면에 출력되기 전에 수행할 내용
//Control 을 배치하는 패널을  생성 
Panel p = new Panel();
//텍스터 필드 1개와 텍스트 에어리어 1개 및 버튼 2개 배치
TextField tf = new TextField(20);
p.add(tf);
TextArea ta = new TextArea(10,50);
p.add(ta);
Button bt1= new Button("복사");
p.add(bt1);
Button bt2= new Button("종료");
p.add(bt2);

//이벤트 라우팅
ActionListener btnListener = new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
String title = e.getActionCommand();
if(title.equals("복사")) {
String text = tf.getText();
ta.setText(text);
tf.setText("");
}else if(title.equals("종료")) {
System.exit(0);
}
}
};

// //버튼의 이벤트 처리를 위한 객체 생성 
// ActionListener listener1 = new ActionListener() {
//
// @Override
// public void actionPerformed(ActionEvent e) {
// //String msg = tf.getText();
// ta.setText(e.getActionCommand()+" : "+e.getSource()+" :                                                         "+e.getModifiers());
// tf.setText(" ");
// }
//
// };
//이벤트 처리 객체와 버튼을 연결
bt1.addActionListener(btnListener);
bt2.addActionListener(btnListener);

//성별을 선택할 수 있는 라디오 버튼 만드릭
CheckboxGroup gender = new CheckboxGroup();
Checkbox man = new Checkbox("남자", gender, true);
Checkbox woman = new Checkbox("여자", gender, false);
p.add(man);
p.add(woman);
ItemListener itemListener = new ItemListener() {

@Override
public void itemStateChanged(ItemEvent e) {
tf.setText(e.getItem().toString());
}
};
man.addItemListener(itemListener);
woman.addItemListener(itemListener);
// KeyListener keyListener = new KeyListener() {
//
// @Override
// public void keyPressed(KeyEvent e) {
// System.out.println("여기 들어왔니?");
// //tf.setText(e.getKeyCode()+"");
// ta.setText(e.getKeyChar()+"");
// }
//
// @Override
// public void keyReleased(KeyEvent e) {
// }
//
// @Override
// public void keyTyped(KeyEvent e) {
// // TODO Auto-generated method stub
//
// }
//
// };
// //현재 프레임의 키보드 이벤트연결 
// tf.addKeyListener(keyListener);
add(p);
setTitle("이벤트 처리");
setBounds(100,100,400,300);
setVisible(true);

//윈도우가 화면에 출력된 후 수행할 내용 

}
}






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();

}


}



package java0115;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class AnimationWindow extends JFrame {
private static final long seriavlVersionUID = 1L;
public AnimationWindow() {
setLayout(null);
JPanel p  = new JPanel();
Icon icon = new ImageIcon("C:\\Users\\K.W.S\\Pictures\\Saved Pictures\\10.png");
JLabel lbl = new JLabel(icon);
p.setBounds(10, 10, 600, 600);
p.add(lbl);
add(p);
setTitle("ㅂㅇㄹ");
setBounds(100,100,1000,1000);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
String [] imgs = {"1.png","2.png","3.png","4.png","10.png"};
int idx=0;
while(true) {
System.out.println("들어오긴했어 "+idx);
idx=idx+1;
try {
Thread.sleep(500);
Icon icon1 = new ImageIcon("C:\\Users\\K.W.S\\Pictures\\Saved Pictures\\"
+ imgs[idx%imgs.length]);
lbl.setIcon(icon1);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}

             




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);

}

}