SWT Event 처리 (Event and Listener)

SWT이벤트 처리는 일반 다른 개발환경의 이벤트 처리와 크게 다르지 않다. 화면에 보여지는 Control객체에 처리할 이벤트 리스너를 등록하여 주고 익명 클래스로 지정된 이벤트 리스너를 구현하여 주면된다. (안드로이드 개발과 동일)



SWT 이벤트 처리 과정

  • OS 이벤트 큐 : 사용자의 동작을 감시하고 목록을 관리한다.
  • Display : OS 이벤트 큐의 목록을 정렬하고 readAndDispatch()메소드와 msg 필드를 통해 핸들링할 이벤트를 가져온다.
  • 최상위 Shell : Display가 전달해준 이벤트를 자식 위젯에게 전달한다.
  • 위젯 : 이벤트 타입에 해당하는 리스너가 등록된 경우 위젯은 리스너 인터페이스에게 이벤트를 전달한다.
  • 리스너 인터페이스 : 실제 구현된 이벤트 핸들링 메소드를 수행시킨다.


TypedEvent and TypedListener

SWT에 있는 대부분의 Event의 상위 클래스는 TypedEvent이고, 대부분의 Listener의 상위 클래스는 TypedListener이다. 실제 사용하는 것은 TypedEvent하위 이벤트 구현체이고, TypedListener의 하위 이벤트 리스너 구현체이다. 각 위젯은 특정 이벤트에 해당하는 이벤트 리스너를 구현하여 동작시키는 방식이다. 즉, 버튼의 경우는 MouseEvent를 처리할 필요가 있음으로, MouseEventListener를 구현하여 add하면 되고, InputText의 경우는 KeyEvent를 처리 할 필요가 있음으로 KeyListener를 구현하면 된다.


이벤트에 유형에 따라서 동작하는 이벤트리스너가 다르고, GUI컴포짓에 따라서 어떤 이벤트 리스너는 동작하지 않기 때문에 아래 표를 참고하여 상호작용이 가능한 GUI컴포지트에 관련된 이벤트 리스너를 구현해야 한다.


 이벤트 (TypedEvent 하위)

 리스너 (TypedListener 하위)

 리스너 메소드

 GUI컴포지트

 ArmEvent

 ArmListener

 widgetArmed()

 MenuItem

 ControlEvent

 ControlListener

 controlMoved()

 controlResized()

 Control, TableColum,  Tracker

 DisposeEvent

 DisposeListener

 widgetDisposed()

 Widget

 FocusEvent

 FocusListener

 focusGained()

 focusLost()

 Control

 HelpEvent

 HelpListener

 helpRequested()

 Control, Menu, MenuItem

 KeyEvent

 KeyListener

 keyPressed()

 keyReleased()

 Control

 MenuEvent

 MenuListener

 menuHidden()

 menuShown()

 Menu

 ModifyEvent

 ModifyListener

 modifyText()

 CCombo, Combo, Text,

 StyledText

 MouseEvent

 MouseListener

 mouseDoubleClick()

 mouseDown()

 mouseUp()

 Control

 MouseMoveEvent

 MouseMoveListener

 mouseMove()

 Control

 MouseTrackEvent

 MouseTrackListener

 mouseEnter()

 mouseExit()

 mouseHover()

 Control

 PaintEvent

 PaintListener

 paintControl()

 Control

 SelectionEvent

 SelectionListener

 widgetDefaultSelected()

 widgetSelected()

 Button, CCombo, Combo,

 CoolItem, CTabFolder, List,

 MenuItem, Sash, Scale,

 ScrollBar, Slider,

 SytledText, TabFolder,

 Table, TableCursor,

 TableColumn, TableTree,

 Text, ToolItem, Tree

 ShellEvent

 ShellListener

 shellActivated()

 shellClosed()

 shellDeactivated()

 shellDeiconified()

 shellIconified()

 Shell

 TraverseEvent

 TraverseListener

 keyTraversed()

 Control

 TreeEvent

 TreeListener

 treeCollapsed()

 treeExpanded()

 Tree, TableTree

 VerifyEvent

 VerifyListener

 verifyText()

 Text, StyledText

- SWT Event 클래스와 관련 리스너, GUI 컴포지트-


또한 Event클래스에는 발생된 이벤트에 따른 정보를 제공하기 위한 맴버 필드를 갖는다. 이벤트 리스너는 이 이벤트의 필드로 부터 이벤트에 대한 정보에 접근 할 수 있다. 각 하위 TypeEvent는 추가적인 데이터를 필드를 갖기도 한다.


 TypedEvent 필드

 기능

 data

 Event 핸들러에서 사용하는 정보 

 display

 Event가 발생한 디스플레이 

 source

 Event를 발생시킨 컴포넌트 

 time

 Event가 발생한 시간 

 widget

 Event를 발생시킨 위젯  

- TypeEvent의 일반적인 데이터 필드 -




TypedEvent-Listener 처리 예시

Button 생성 후 Mouse Down시 System 메시지를 출력하는 간단한 예제.

Override된 메소드 내부에서는 이벤트가 발생한 객체에 Event.getSource()를 통해서 접근한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Button Mouse 이벤트 리스너 지정
btn.addMouseListener(new MouseListener() {
            
    // MouseListener Interface Method Override
    @Override
    public void mouseUp(MouseEvent arg0) {
    }
                    
    @Override
    public void mouseDown(MouseEvent arg0) {
        // 이벤트를 발생시킨 Widget 획득
        Button btn = (Button) arg0.getSource();
                
        // 필요작업 코딩
        System.out.println("마우스 DOWN");
    }
                    
    @Override
    public void mouseDoubleClick(MouseEvent arg0) {          
    }
});
cs



TypedAdapter 처리 예시

위에 예시를 보면 실제 내가 필요한 이벤트 처리는 mouseDown 메소드만 오버라이드 하고 있는데, MouseListener가 interface 형태이기 때문에 불필요하게 mouseDoubleClick, mouseUp메소드 까지 override 받아 비어있는 메소드 블락을 강제로 만들어야만 한다. 이런 불필요한 수고를 덜고자 사용되는 것이 Adapter클래스이다. Adapter는추상 클래스로 TypedListener를 구현하고 필요한 각 메소드의 기본 블락을 제공한다. Listener 인터페이스 대신 Adapter를 사용하면 자신이 원하는 메소드만 Override하여 사용하면 된다. (물론 직접 Adapter클래스를 생성하여 사용하여도 무방하다)

1
2
3
4
5
6
7
// Button Mouse Adapter 지정
btn.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseDown(MouseEvent e) {
        System.out.println("mouse down");
    }
});
cs

실제 사용하지 않는 메소드는 Override하지 않아도 되기 때문에 소스코드가 간결하다. 

아래는 SWT에서 제공하는 Adapter 목록이다.


Typed Listener

 Adapter

 ControlListener

 ControlAdapter 

 FocusListener

 FocusAdapter

 KeyListener

 KeyAdapter

 MenuListener

 MenuAdapter

 MouseListener

 MouseAdapter

 MouseTrackListener

 MouseTrackAdapter

 SelectionListener

 SelectionAdapter

 ShellListener

 ShellAdapter

 TreeListener

 TreeAdapter

- Type Listener와 상응하는 Adapter -



무형이벤트(Event)와 무형리스너(Listener)처리 예시

TypedEvent와 TypedListener는 기본적으로 이벤트의 범위를 특정 이벤트로 좁혀서 사용자가 원하는 특정 동작만 처리하록 한다. 하지만 이러한 명확한 Typed 방식은 가령 MouseEvent와 KeyEvent를 동시에 처리하는 Widget이 존재하는 경우는 소스코드가 길고 별도의 리스너 인터페이스를 두개나 구현해주어야 하여 불편하다. 이런 경우 사용되는 것이 무형 Event, 무형 Listener이다. 


무형 Event와  무형 Listener는 특정한 이벤트에 대한 만능 리스너를 만드는 것을 가능하게 한다.


[Listener생성]

Listener인터페이스 구현체를 생성하여 handleEvent 메소드를 구현하여 처리 할 이벤트 Type에 따라서 분기처리를 작성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 무형 Listener 생성
Listener listener = new Listener() {
    @Override
    public void handleEvent(Event paramEvent) {
        
        System.out.println("이벤트 시작");
        
        switch (paramEvent.type) {
            // 키다운 이벤트 처리
            case SWT.KeyDown:
                System.out.println("Key Press : " + paramEvent.character);
                break;
            
            // 마우스 다운 이벤트 
            case SWT.MouseDown:
                if( paramEvent.button == 1 ) System.out.println("Mouse left Down");
                if( paramEvent.button == 2 ) System.out.println("Mouse whell Down");
                if( paramEvent.button == 3 ) System.out.println("Mouse right Down"); 
                break;
            
            // 마우스 더블 클릭 
            case SWT.MouseDoubleClick:
                System.out.println("Mouse Double Click");
                break;
        }
        
        System.out.println("이벤트 종료");
    }
};
cs


[Listener적용]

Listener객체인 listener를 Button 객체에 addListener 메소드를 이용하여 적용하여 준다.

1
2
3
4
5
6
7
8
// Button 생성
Button btn = new Button(shell, SWT.PUSH);
btn.setText("버튼 ");
 
// 버튼에 무형 Listener 지정
btn.addListener(SWT.KeyDown, listener);
btn.addListener(SWT.MouseDown, listener);
btn.addListener(SWT.MouseDoubleClick, listener);
cs


이렇게 처리하게 되면 하나의 Listener를 통해서 여러개 이벤트 처리가 가능해 진다.

여기서 Listener생성 소스를 보면 Event.type를 이용해 각 이벤트를 구분하는데 사용가능 한 유효값은 아래 표를 참고하자.

 Type 필드 유효값

  SWT.Activate

 SWT.FocusIn

 SWT.KeyUp

 SWT.Move

  SWT.Arm

 SWT.FocusOut

 SWT.MenuDetect

 SWT.None

  SWT.Close

 SWT.Expand

 SWT.Modify

 SWT.Paint

  SWT.Collapse

 SWT.HardKeyDown

 SWT.MouseDoubleClick

 SWT.Resize

  SWT.Deactivate

 SWT.HardKeyUp

 SWT.MouseEnter 

 SWT.Selection

  SWT.DefaultSelection

 SWT.Help

 SWT.MouseExit

 SWT.Show

  SWT.Deiconify

 SWT.Hide

 SWT.MouseHover

 SWT.Traverse

  SWT.Dispose

 SWT.Iconify

 SWT.MouseMove

 SWT.Verify

  SWT.DragDetect SWT.KeyDown  SWT.MouseUp 

  


참고사항

Eclipse.org 커뮤니티에서 무형 이벤트와 리스너를 사용하지 않도록 권고하고 있음. 굳이 필요하지 않으면 쓰지 않도록 하고 실제로도 TypeListener를 사용하면 되기 때문에 많이 쓰일 일은 없을 것 같다.


이 글을 공유하기

댓글

Email by JB FACTORY