IT 정보/자바/JSP/EJB

[자바/SCJP/JAVA/자바/SCJP/JAVA]자바 이벤트

김윤석 2007. 12. 14. 17:45
대부분의 프로그램은 사용자의 명령어를 기다리고 있다가, 사용자의 액션에 반응해서 작동하게 된다. 마우스 버튼 클릭, 더블클릭, 마우스 이동 등의 모든 사용자 액션에 대해 응답하는 형태로 작동하도록 프로그래밍하는 것을 이벤트-드리븐(event-driven)프로그래밍이라고 한다. 윈도우 환경에서는 대부분의 응용프로그램이 이벤트-드리븐 프로그래밍 방식으로 작성된다.
자바의 AWT에서도 물론 이벤트-드리븐 프로그래밍을 지원한다. 자바에서는 모든 사용자의 액션을 이벤트라는 클래스로 표현하고 있다. 사용자의 액션에의해 발생된 이벤트 객체는 사용자의 액션에 관련된 정보를 가지고 있다.
  • 이벤트 타입 정보 : 예) 마우스 클릭, 키보드 키 누름 등
  • 이벤트 타겟 : 예) 사용자가 클릭한 버튼, 사용자가 입력한 텍스트 필드 등
  • 이벤트가 발생한 시각
  • 이벤트가 발생한 X-Y 좌표 위치 : 예) 마우스가 클릭된 위치 등
  • 눌려진 키보드 키 : 예) 사용자가 누른 키보드의 키값
  • 아규먼트
  • 모디파이어 키의 상태 : 예) Shift, Cntl 등
컴포넌트(Component) 클래스에서 이벤트를 처리하는 함수들이 정의되어 있다. 프로그래머는 원하는 경우에 이벤트 처리 함수를 overriding 방법을 통해 자신이 원하는 형태로 정의할 수 있다. 이벤트 처리 함수들 중에 가장 중요한 것은 handleEvent()라는 함수이다. handleEvent()는 모든 이벤트를 처리할 수 있는 함수이다. 컴포넌트에 이벤트가 발생되면 handleEvent()함수가 자동적으로 호출된다. handleEvent()는 모든 이벤트를 처리할 수 있지만 handleEvent() 함수 사용은 가급적 자제하는 것이 좋다. 왜냐하면, 모든 이벤트를 하나의 함수에서 모두 처리하기 때문에 함수의 크기가 너무 커진다. 이것은 프로그램 작성, 수정, 이해하는데 많은 장애 요인이 된다. 두번째 이유로는 많은 이벤트를 처리함으로서 이벤트 간에 상호 작용에 의해 원하지 않는 결과를 가져올 수 있다.

컴포넌트(Component) 클래스에서는 handleEvent()이외에 특정 이벤트만 처리할 수 있는 함수들을 제공한다. 따라서 이런 특정 이벤트만 처리하는 함수가 정의되어 있으면, 원하는 이벤트가 발생하는 경우 handleEvent()함수가 자동적으로 해당되는 이벤트 처리 함수를 호출한다. 이러한 함수들로는 다음과 같은 것들이 있다.




모든 이벤트 처리 함수들은 적어도 하나의 아규먼트(Event)를 가지며, boolean 값을 리턴한다. 이벤트 처리 함수가 false를 리턴하면, 이것은 이벤트 핸들러가 이벤트를 상위 컴포넌트 계층으로 전달한다는 것을 의미한다. 반대로, true를 리턴하면 이벤트는 더 이상 전달되지 않고 현재 이벤트 처리 함수에서 처리된다는 것을 의미한다. handleEvent()함수는 모든 이벤트가 적당한 이벤트 처리 함수에 전달되도록 super.handleEvent()를 리턴 값으로 호출해주어야 한다.
 public  boolean handleEvent(Event e) {
    if(e.target instanceof Scrollbar) {
         textField.setText(String.valueOf(slider.getValue()));
    }
    return super.handleEvent(e);
}



다음과 같은 모양의 애플릿을 작성하였다. 이 애플릿은 사용자가 버튼을 클릭하면 텍스트 영역에 이벤트가 전달되는 과정을 기록한다.


다음 그림은 앞 그림에서 본 애플릿의 계층적 구성도이다. 그림에서 화살표는 사용자가 버튼을 클릭하는 경우 이벤트가 상위 계층으로 전달되는 과정을 보여주고 있다.


파일 Example1.java
import java.awt.*;

class NewButtonEx1 extends Button
{
   private TextArea ta;

   public NewButtonEx1(String str, TextArea ta)
   {
      super(str);
      this.ta = ta;
   }

   public boolean handleEvent(Event evt)
   {
      if (evt.id == Event.ACTION_EVENT)
      {
         ta.appendText("Button " + getLabel() + " saw action...\n");
      }

      return super.handleEvent(evt);
   }
}

class NewPanelEx1 extends Panel
{
   private String str;
   private TextArea ta;

   public NewPanelEx1(String str, TextArea ta)
   {
      super();
      this.str = str;
      this.ta = ta;
   }

   public Insets insets()
   {
      return new Insets(5, 5, 5, 5);
   }

   public void paint(Graphics g)
   {
      g.drawRect(0, 0, size().width - 1, size().height - 1);
   }
        
   public boolean handleEvent(Event evt)
   {
      if (evt.id == Event.ACTION_EVENT)
      {
         ta.appendText("Panel " + str + " saw action...\n");
      }
      else if (evt.id == Event.MOUSE_DOWN)
      {
         ta.appendText("Panel " + str + " saw mouse down...\n");
      }

      return super.handleEvent(evt);
   }
}

public class Example1 extends java.applet.Applet
{
   TextArea ta = new TextArea();

   public void init()
   {
      setLayout(new BorderLayout());

      add("Center", ta);

      NewPanelEx1 p1 = new NewPanelEx1("1", ta);
      NewPanelEx1 p2 = new NewPanelEx1("2", ta);

      p2.add(new NewButtonEx1("One", ta));
      p2.add(new NewButtonEx1("Two", ta));

      p1.add(p2);

      add("South", p1);
   }

   public Dimension preferredSize()
   {
      return new Dimension(400, 230);
   }

   public Insets insets()
   {
      return new Insets(5, 5, 5, 5);
   }

   public boolean handleEvent(Event evt)
   {
      if (evt.id == Event.ACTION_EVENT)
      {
         ta.appendText("Applet saw action...\n\n");
      }
      else if (evt.id == Event.MOUSE_DOWN)
      {
         ta.appendText("Applet saw mouse down...\n\n");
      }

      return super.handleEvent(evt);
   }

   public static void main(String [] args)
   {
      Frame f = new Frame("Example 1");

      Example1 ex = new Example1();

      ex.init();

      f.add("Center", ex);

      f.pack();
      f.show();
   }
}





다음 그림은 이벤트를 테스트하는 애플릿이다. 각종 이벤트가 발생할 때마다 System.out.println()을 이용해서 화면에 내용을 출력하도록 하였다.


파일 EventTutor.java
import java.applet.Applet;
import java.awt.*;

public class EventTutor extends Applet {

  public void init() {
        System.out.println("init event");
  }
 
  public void paint(Graphics g) {
        System.out.println("paint event");
  }
   
  public void start() {
        System.out.println("start event");
  }

  public void destroy() {
        System.out.println("destroy event");
  }

  public void update(Graphics g) {
        System.out.println("update event");
  }

  public boolean mouseUp(Event e, int x, int y) {
        System.out.println("mouseUp event");
        return false;
  }

  public boolean mouseDown(Event e, int x, int y) {
                System.out.println("mouseDown");
                return false;
  }

  public boolean mouseDrag(Event e, int x, int y) {
        System.out.println("mouseDrag event");
        return false;
  }

  public boolean mouseMove(Event e, int x, int y) {
        System.out.println("mouseMove event");
        return false;
  }

  public boolean mouseEnter(Event e, int x, int y) {
        System.out.println("mouseEnter event");
        return false;
  }

 public boolean mouseExit(Event e, int x, int y) {
        System.out.println("mouseExit event");
        return false;
  }

  public void getFocus() {
        System.out.println("getFocus event");
  }

  public void gotFocus() {
        System.out.println("gotFocus event");
  }

  public void lostFocus() {
        System.out.println("lostFocus event");
  }

  public boolean keyDown(Event e, int x) {
        System.out.println("keyDown event");
        return true;
  }
}





다음은 사각형을 그리는 애플릿의 예이다.


파일 drawRec.java
import java.applet.*;
import java.awt.*;

public class DrawRec extends Applet {
        int  startX, startY, w, h;

        public void init() {
                startX = 0;
                startY = 0;
                w = 0;
                h = 0;
        }

        public void paint(Graphics g) {
                g.drawRect(startX, startY, w, h);
        }

        public boolean mouseDown(Event e, int x, int y) {
                startX = x;
                startY = y;
                return true;
        }

        public boolean mouseDrag(Event e, int x, int y) {
                w = Math.abs(startX -x);
                h = Math.abs(startY - y);
                repaint();
                return true;
        }

        public boolean mouseUp(Event e, int x, int y) {
                w = Math.abs(startX -x);
                h = Math.abs(startY - y);
                repaint();
                return true;
        }
}

자바추천학원:
http://www.it-bank.or.kr/prom/java_main.htm