객체지향프로그래밍 이벤트처리 손시운 ssw5176@kangwon.ac.kr
이벤트 - 구동프로그래밍 이벤트 - 구동프로그래밍 (event-driven programming): 프로그램의실행이이벤트의발생에의하여결정되는방식 2
이벤트처리과정 3
이벤트리스너 발생된이벤트객체에반응하여서이벤트를처리하는객체를이벤트리스너 (event listener) 라고한다. 4
이벤트처리과정 (1) 이벤트리스너클래스를작성한다. class MyListener implements ActionListener { public void actionperformed(actionevent e) {... // Action 이벤트를처리하는코드가여기에들어간다. 5
이벤트처리과정 (2) 이벤트리스너를이벤트소스에등록한다. public class MyFrame extends JFrame { public MyFrame() // 생성자에서컴포넌트를생성하고추가한다. { button = new JButton(" 동작 "); // 버튼생성 button.addactionlistener(new MyListener());... 이벤트리스너를컴포넌트에붙인다. 6
이벤트객체 EventObject 클래스를상속받는다. ( 예 ) MouseEvent 클래스 이벤트를발생시킨이벤트소스등의여러가지정보를제공한다. public void actionperformed(actionevent e) { button = (JButton)e.getSource();... 7
이벤트처리기를어디에 (1) 독립적인클래스로이벤트처리기를작성 (2) 내부클래스로이벤트처리기를작성 이벤트처리방법 (3) 프레임클래스에이벤트처리를구현 (4) 무명클래스를사용하는방법 (5) 람다식을이용하는방법 8
(1) 독립적인클래스방법 import javax.swing.*; import java.awt.event.*; class MyListener implements ActionListener { public void actionperformed(actionevent e) { JButton button = (JButton) e.getsource(); button.settext(" 마침내버튼이눌려졌습니다."); // label.settext(" 마침내버튼이눌려졌습니다."); 9
(1) 독립적인클래스방법 class MyFrame extends JFrame { private JButton button; private JLabel label; public MyFrame() { this.setsize(300, 200); this.setdefaultcloseoperation(jframe.exit_on_close); this.settitle(" 이벤트예제 "); JPanel panel = new JPanel(); button = new JButton(" 버튼을누르시오 "); label = new JLabel(" 아직버튼이눌려지지않았습니다 "); button.addactionlistener(new MyListener()); panel.add(button); panel.add(label); this.add(panel); this.setvisible(true); public class ActionEventTest1 { public static void main(string[] args) { MyFrame t = new MyFrame(); 10
(1) 독립적인클래스방법 11
(2) 내부클래스방법 만약 MyListener 라는클래스를별도의클래스로하면 MyFrame 안의멤버 변수들을쉽게사용할수없다. 일반적으로 MyListener 클래스를내부클래스로만든다. 12
(2) 내부클래스방법 class MyFrame extends JFrame { private JButton button; private JLabel label; public MyFrame() { this.setsize(300, 200); this.setdefaultcloseoperation(jframe.exit_on_close); this.settitle(" 이벤트예제 "); JPanel panel = new JPanel(); button = new JButton(" 버튼을누르시오 "); label = new JLabel(" 아직버튼이눌려지지않았습니다 "); button.addactionlistener(new MyListener()); panel.add(button); panel.add(label); this.add(panel); this.setvisible(true); 13
(2) 내부클래스방법 private class MyListener implements ActionListener { public void actionperformed(actionevent e) { if (e.getsource() == button) { label.settext(" 마침내버튼이눌려졌습니다."); public class ActionEventTest { public static void main(string[] args) { MyFrame t = new MyFrame(); 내부클래스 label 에접근할수있다. 14
(2) 내부클래스방법 15
(3) MyFrame 에서이벤트도처리하는방법 더많이사용되는방법은 MyFrame 클래스가 JFrame 을상속받으면서동시 에 ActionListener 인터페이스도구현하는경우이다.... class MyFrame extends JFrame implements ActionListener {... public MyFrame() {... button = new JButton(" 버튼을누르시오 "); label = new JLabel(" 아직버튼이눌려지지않았습니다 "); button.addactionlistener(this);... public void actionperformed(actionevent e) { if (e.getsource() == button) { label.settext(" 마침내버튼이눌려졌습니다."); 이벤트도처리... 16
(4) 무명클래스를사용하는방법 class MyFrame extends JFrame {... public MyFrame() {... button = new JButton(" 버튼을누르시오 "); button.addactionlistener(new ActionListener() { public void actionperformed(actionevent e) { if (e.getsource() == button) { label.settext(" 마침내버튼이눌려졌습니다."); );... 안드로이드에서많이사용된다! 17
(5) 람다식을이용하는방법 import javax.swing.*; class MyFrame extends JFrame { private JButton button; private JLabel label; public MyFrame() { this.setsize(300, 200); this.setdefaultcloseoperation(jframe.exit_on_close); this.settitle(" 이벤트예제 "); JPanel panel = new JPanel(); button = new JButton(" 버튼을누르시오 "); label = new JLabel(" 아직버튼이눌려지지않았습니다 "); button.addactionlistener(e -> { label.settext(" 마침내버튼이눌려졌습니다."); ); panel.add(button); panel.add(label); this.add(panel); this.setvisible(true); 18
LAB: 키패드만들기 숫자를입력할수있는키패드프로그램을작성하여보자. 19
SOLUTION public class KeyPad extends JFrame implements ActionListener { private JTextField txt; private JPanel panel; public KeyPad() { txt = new JTextField(20); add(txt, BorderLayout.NORTH); panel = new JPanel(); panel.setlayout(new GridLayout(3, 3)); add(panel, BorderLayout.CENTER); for (int i = 1; i <= 9; i++) { JButton btn = new JButton("" + i); btn.addactionlistener(this); btn.setpreferredsize(new Dimension(100, 100)); panel.add(btn); pack(); setdefaultcloseoperation(exit_on_close); setvisible(true); 20
SOLUTION @Override public void actionperformed(actionevent e) { String actioncommand = e.getactioncommand(); txt.settext(txt.gettext() + actioncommand); public static void main(string[] args) { new KeyPad(); 21
LAB: 퍼즐게임 타일을클릭하면비어있는옆의공간으로이동하는퍼즐게임을작성해보자. 22
SOLUTION class MyButton extends JButton { static int count=0; int index; public MyButton(String s) { super(s); index = count++; 23
public class Puzzle extends JFrame implements ActionListener { SOLUTION MyButton[] buttons; MyButton reset; public Puzzle() { super("puzzle"); JPanel panel = new JPanel(); panel.setlayout(new GridLayout(0, 3, 2, 2)); buttons= new MyButton[9]; for(int i=0; i<8; i++) buttons[i] = new MyButton(""+(i+1)); buttons[8] = new MyButton(" "); for(int i=0; i<9; i++) panel.add(buttons[i]); for(int i=0; i<9; i++) buttons[i].addactionlistener(this); add(panel, BorderLayout.CENTER); reset = new MyButton("reset"); reset.setbackground(color.red); reset.setforeground(color.yellow); add(reset, BorderLayout.SOUTH); setsize(300, 300); setvisible(true); setdefaultcloseoperation(jframe.exit_on_close); 24
SOLUTION public void actionperformed(actionevent e) { MyButton b = (MyButton) e.getsource(); if( b.gettext().equals(" ")==true) return; if( b.index == 7 ){ if( buttons[4].gettext().equals(" ") ) { buttons[4].settext(b.gettext()); b.settext(" "); if( buttons[6].gettext().equals(" ") ) { buttons[6].settext(b.gettext()); b.settext(" "); if( buttons[8].gettext().equals(" ") ) { buttons[8].settext(b.gettext()); b.settext(" "); public static void main(string[] args) { new Puzzle(); 25
LAB: 가위바위보게임 가위, 바위, 보게임을작성하여보자. 26
SOLUTION public class RockPaperScissor extends JFrame implements ActionListener { static final int ROCK = 0, PAPER = 1, SCISSOR = 2; private JPanel panel; private JTextField output, information; private JButton rock, paper, scissor; 27
SOLUTION public RockPaperScissor() { settitle(" 가위, 바위, 보 "); setsize(400, 300); setdefaultcloseoperation(exit_on_close); panel = new JPanel(); panel.setlayout(new GridLayout(0, 3)); information = new JTextField(" 아래의버튼중에서하나를클릭하시오!"); output = new JTextField(20); rock = new JButton("ROCK"); paper = new JButton("PAPER"); scissor = new JButton("SCISSOR"); rock.addactionlistener(this); paper.addactionlistener(this); scissor.addactionlistener(this); panel.add(rock); panel.add(paper); panel.add(scissor); add(information, BorderLayout.NORTH); add(panel, BorderLayout.CENTER); add(output, BorderLayout.SOUTH); setvisible(true); 28
SOLUTION public static void main(string[] args) { RockPaperScissor gui = new RockPaperScissor(); @Override public void actionperformed(actionevent e) { Random random = new Random(); int computer = random.nextint(3); if (e.getsource() == rock) { if (computer == SCISSOR) output.settext(" 사용자승리 "); else if (computer == ROCK) output.settext(" 비겼음 "); else output.settext(" 컴퓨터승리 "); else if (e.getsource() == paper) { if (computer == ROCK) output.settext(" 사용자승리 "); else if (computer == PAPER) output.settext(" 비겼음 "); else output.settext(" 컴퓨터승리 "); else if (e.getsource() == scissor) { if (computer == PAPER) output.settext(" 사용자승리 "); else if (computer == SCISSOR) output.settext(" 비겼음 "); else output.settext(" 컴퓨터승리 "); 29
이벤트의분류 스윙컴포넌트에의하여지원되는이벤트는크게두가지의카테고리로나 누어진다. 30
저수준이벤트 모든컴포넌트에서발생한다. 자주발생하므로이벤트처리에너무많은시간을사용하면안된다. 31
의미적이벤트 일부컴포넌트에서만발생한다. 가능하다면저수준이벤트보다의미적이벤트를사용한다. 32
액션이벤트 사용자가버튼을클릭하는경우 사용자가메뉴항목을선택하는경우 사용자가텍스트필드에서엔터키를누르는경우 33
액션이벤트예제 두개의버튼을만들어서패널의배경색을변경하는프로그램을작성하여 보자. 이벤트리스너는하나만생성한다. 34
액션이벤트예제 class MyFrame extends JFrame { private JButton button1; private JButton button2; private JPanel panel; public MyFrame() { this.setsize(300, 200); this.setdefaultcloseoperation(jframe.exit_on_close); this.settitle(" 이벤트예제 "); panel = new JPanel(); button1 = new JButton(" 노란색 "); button1.addactionlistener(new MyListener()); panel.add(button1); button2 = new JButton(" 핑크색 "); button2.addactionlistener(new MyListener()); panel.add(button2); this.add(panel); this.setvisible(true); 35
액션이벤트예제 private class MyListener implements ActionListener { public void actionperformed(actionevent e) { if (e.getsource() == button1) { panel.setbackground(color.yellow); else if (e.getsource() == button2) { panel.setbackground(color.pink); public class ChangeBackground { public static void main(string[] args) { MyFrame t = new MyFrame(); 36
실행결과화면 37
Key 이벤트 KeyListener 인터페이스구현 메소드 keytyped(keyevent e) keypressed(keyevent e) keyreleased(keyevent e) 설명사용자가글자를입력했을경우에호출사용자가키를눌렀을경우에호출사용자가키에서손을떼었을경우에호출 38
Key 이벤트예제 키보드에서문자가입력되면문자코드와키코드, ALT 나 SHIFT 키의상태를 텍스트영역에출력한다. 39
키이벤트예제 public class KeyEventTest extends JFrame implements KeyListener { private JPanel panel; private JTextField field; private JTextArea area; public KeyEventTest() { panel = new JPanel(new GridLayout(0, 2)); panel.add(new JLabel(" 문자를입력하시오 : ")); field = new JTextField(10); panel.add(field); area = new JTextArea(3, 30); add(panel, BorderLayout.NORTH); add(area, BorderLayout.CENTER); field.addkeylistener(this); settitle("keyevent Test"); setsize(400, 200); setvisible(true); 40
키이벤트예제 public static void main(string[] args) { new KeyEventTest(); public void keytyped(keyevent e) { // (3) display(e, "Key Typed "); public void keypressed(keyevent e) { display(e, "Key Pressed "); public void keyreleased(keyevent e) { display(e, "Key Released "); protected void display(keyevent e, String s) { char c = e.getkeychar(); int keycode = e.getkeycode(); String modifiers = "Alt: " + e.isaltdown() + "Ctrl: " + e.iscontroldown() + "Shift: " + e.isshiftdown(); area.append("" + s + " 문자 " + c + "( 코드 : " + keycode + ") " + modifiers + "\n"); 41
실행결과 42
자동차게임예제 키보드의화살표키로움직이는자동차애플리케이션을작성하여보자. 43
자동차게임예제... class MyPanel extends JPanel { BufferedImage img = null; int img_x = 100, img_y = 100; public MyPanel() { try { img = ImageIO.read(new File("car.gif")); catch (IOException e) { System.out.println("no image"); System.exit(1); addkeylistener(new KeyListener() { public void keypressed(keyevent e) { int keycode = e.getkeycode(); switch (keycode) { case KeyEvent.VK_UP: img_y -= 10; break; case KeyEvent.VK_DOWN: img_y += 10; break; case KeyEvent.VK_LEFT: img_x -= 10; break; case KeyEvent.VK_RIGHT: img_x += 10; break; repaint(); 44
자동차게임예제 public void keyreleased(keyevent arg0) { public void keytyped(keyevent arg0) { ); this.requestfocus(); setfocusable(true); public void paintcomponent(graphics g) { super.paintcomponent(g); g.drawimage(img, img_x, img_y, null); public class CarGameTest extends JFrame { public CarGameTest() { setsize(300, 300); setdefaultcloseoperation(jframe.exit_on_close); add(new MyPanel()); setvisible(true); public static void main(string[] args) { CarGameTest s = new CarGameTest(); 45
실행결과 46
LAB: 신호등 신호등을구현하여보자. 버튼을누르면신호가변경되도록한다. 47
SOLUTION class MyPanel extends JPanel implements ActionListener { boolean flag = false; private int light_number = 0; public MyPanel() { setlayout(new BorderLayout()); JButton b = new JButton("traffic light turn on"); b.addactionlistener(this); add(b, BorderLayout.SOUTH); 48
@Override SOLUTION protected void paintcomponent(graphics g) { super.paintcomponent(g); g.setcolor(color.black); g.drawoval(100, 100, 100, 100); g.drawoval(100, 200, 100, 100); g.drawoval(100, 300, 100, 100); if (light_number == 0) { g.setcolor(color.red); g.filloval(100, 100, 100, 100); else if (light_number == 1) { else { @Override g.setcolor(color.green); g.filloval(100, 200, 100, 100); g.setcolor(color.yellow); g.filloval(100, 300, 100, 100); public void actionperformed(actionevent arg0) { if (++light_number >= 3) light_number = 0; repaint(); 49
SOLUTION public class MyPanelTest extends JFrame { public MyPanelTest() { add(new MyPanel()); setsize(300, 500); setvisible(true); public static void main(string[] arg) { new MyPanelTest(); 50
Mouse 이벤트 51
MOUSELISTENER 인터페이스 52
마우스이벤트순서 Mouse pressed (# of clicks: 1) X=118 Y=81 Mouse released (# of clicks: 1) X=118 Y=81 Mouse clicked (# of clicks: 1) X=118 Y=81 53
MOUSEMOTIONLISTENER 인터페이스 54
Mouse 이벤트예제 import javax.swing.*; import java.awt.*; import java.awt.event.*; class MyFrame extends JFrame implements MouseListener, MouseMotionListener { public MyFrame() { settitle("mouse Event"); setsize(300, 200); setdefaultcloseoperation(jframe.exit_on_close); JPanel panel = new JPanel(); panel.addmouselistener(this); panel.addmousemotionlistener(this); add(panel); setvisible(true); 마우스이벤트처리기를붙인다. 55
Mouse 이벤트예제 public void mousepressed(mouseevent e) { display("mouse pressed (# of clicks: " + e.getclickcount() + ")", e); public void mousereleased(mouseevent e) { display("mouse released (# of clicks: " + e.getclickcount() + ")", e); public void mouseentered(mouseevent e) { display("mouse entered", e); public void mouseexited(mouseevent e) { display("mouse exited", e); public void mouseclicked(mouseevent e) { display("mouse clicked (# of clicks: " + e.getclickcount() + ")", e); 56
Mouse 이벤트예제 protected void display(string s, MouseEvent e) { System.out.println(s + " X=" + e.getx() + " Y=" + e.gety()); public void mousedragged(mouseevent e) { display("mouse dragged", e); public void mousemoved(mouseevent e) { display("mouse moved", e); public class MyFrameTest5 { public static void main(string[] args) { MyFrame f=new MyFrame(); 57
LAB: 사각형그리기 마우스를클릭할때마다사각형이화면에그려지는예제를작성하여보자. 58
SOLUTION class Rectangle { int x, y, w, h; class MyPanel extends JPanel implements MouseListener { BufferedImage img = null; int img_x = 0, img_y = 0; Rectangle[] array = new Rectangle[100]; int index = 0; public MyPanel() { this.addmouselistener(this); @Override public void paintcomponent(graphics g) { super.paintcomponent(g); for (Rectangle r : array) if (r!= null) g.drawrect(r.x, r.y, r.w, r.h); 59
SOLUTION @Override public void mousepressed(mouseevent e) { if (index > 100) return; array[index] = new Rectangle2(); array[index].x = e.getx(); array[index].y = e.gety(); array[index].w = array[index].h = 50; index++; repaint(); @Override public void mousereleased(mouseevent e) { @Override public void mouseclicked(mouseevent e) { @Override public void mouseentered(mouseevent e) { @Override public void mouseexited(mouseevent e) { 60
SOLUTION public class MouseEventTest extends JFrame { public MouseEventTest() { setsize(300, 300); settitle(" 마우스로사각형그리기 "); setdefaultcloseoperation(jframe.exit_on_close); add(new MyPanel()); setvisible(true); public static void main(string[] args) { MouseEventTest s = new MouseEventTest(); 61
LAB: 그림그리기 이번에는마우스로화면에그림을그리는프로그램을작성하여보자. 62
SOLUTION class Point { int x, y; class MyPanel extends JPanel implements MouseMotionListener { private int index = 0; Point[] array = new Point[1000]; public MyPanel() { this.addmousemotionlistener(this); @Override public void mousedragged(mouseevent e) { int x = e.getx(); int y = e.gety(); if (index > 1000) return; array[index] = new Point(); array[index].x = e.getx(); array[index].y = e.gety(); index++; repaint(); 63
SOLUTION @Override public void paintcomponent(graphics g) { super.paintcomponent(g); for (Point p : array) if (p!= null) g.drawrect(p.x, p.y, 1, 1); @Override public void mousemoved(mouseevent arg0) { public class Scribble extends JFrame { public Scribble() { setsize(300, 300); settitle(" 마우스로그림그리기 "); setdefaultcloseoperation(jframe.exit_on_close); add(new MyPanel()); setvisible(true); public static void main(string[] args) { Scribble s = new Scribble(); 64
어댑터클래스 인터페이스의경우, 모든메소드를구현하여야한다. 어댑터클래스 (Adaptor Class) 를사용하면원하는메소드만을구현하는것 이가능해진다 인터페이스 ComponentListener ContainerListener FocusListener KeyListener MouseListener MouseMotionListener WindowListener 어댑터클래스 ComponentAdapter ContainerAdapter FocusAdater KeyAdapter MouseAdapter MouseMotionAdapter WindowAdapter 65
리스너를사용하는경우 public class MyClass implements MouseListener { public MyClass() { //... someobject.addmouselistener(this); public void mousepressed(mouseevent e) { public void mousereleased(mouseevent e) { public void mouseentered(mouseevent e) { public void mouseexited(mouseevent e) { public void mouseclicked(mouseevent e) { //... //... 66
어댑터를사용하는경우 public class MyClass extends MouseAdapter { public MyClass() { //... someobject.addmouselistener(this); public void mouseclicked(mouseevent e) { //... 67
LAB: 카운터 카운터증가 버튼을누르면카운터값이하나씩증가되어서화면에표시된 다. 68
SOLUTION class MyCounter extends JFrame implements ActionListener { private JLabel label, label1; private JButton button; private int count = 0; public MyCounter() { JPanel panel = new JPanel(); label = new JLabel("Counter"); panel.add(label); label1 = new JLabel("" + count); label1.setfont(new Font("Serif", // 레이블에폰트를설정한다. Font.BOLD Font.ITALIC, 100)); panel.add(label1); button = new JButton(" 카운터증가 "); panel.add(button); button.addactionlistener(this); add(panel); setsize(300, 200); settitle("my Counter"); setvisible(true); 69
SOLUTION @Override public void actionperformed(actionevent event) { count++; label1.settext(count + " "); public class CounterTest { public static void main(string[] args) { new MyCounter(); 70