자바2009. 1. 4. 17:53

보통 AWT/Swing에서 발생되는 input event는 JVM을 호스팅하고 있는 OS의 native input event를 AWT native 구현체가 Java 객체로 변환하여 전달한 것이다. 그런데 Windows(win32)나 Linux(gtk) API에는 mouse click event가 따로 존재하지 않는다(고 알고 있다). 그러면 Java에서 사용되는 mouse click event는 어디서 생성된 것일까? 아마도 아래 OpenJDK 소스에서 답을 찾을 수 있을 것 같다.

MsgRouting AwtComponent::WmMouseUp(UINT flags, int x, int y, int button)
{
    MSG msg;
    InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);

    SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, TimeHelper::getMessageTimeUTC(),
                   x, y, GetJavaModifiers(), clickCount,
                   (GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ?
                    TRUE : FALSE), GetButton(button), &msg);
    ...
    if (!(m_mouseDragState & GetButtonMK(button))) { // No up-button in the drag-state
        SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED,
                       TimeHelper::getMessageTimeUTC(), x, y, GetJavaModifiers(),
                       clickCount, JNI_FALSE, GetButton(button));
    }
    ...
}

Source:
https://openjdk.dev.java.net/svn/openjdk/jdk/trunk/jdk/src/windows/native/sun/windows/awt_Component.cpp

void
awt_canvas_handleEvent(Widget w, XtPointer client_data,
                       XEvent * event, struct WidgetInfo *winfo,
                       Boolean * cont, Boolean passEvent)
{
    ...

    switch (event->type) {
        ...
        case ButtonRelease:
            ...
            awt_post_java_mouse_event(client_data,
                                      java_awt_event_MouseEvent_MOUSE_RELEASED,
                                      (passEvent == TRUE) ? event : NULL,
                                      event->xbutton.time,
                                      modifiers,
                                      x, y,
                                      (jint) (event->xbutton.x_root),
                                      (jint) (event->xbutton.y_root),
                                      clickCount,
                                      FALSE, 0,
                                      button);

            if (lastPeer == client_data) {
                awt_post_java_mouse_event(client_data,
                                          java_awt_event_MouseEvent_MOUSE_CLICKED,
                                          NULL,
                                          event->xbutton.time,
                                          modifiers,
                                          x, y,
                                          (jint) (event->xbutton.x_root),
                                          (jint) (event->xbutton.y_root),
                                          clickCount,
                                          FALSE, 0,
                                          button);
            }
            ...
    }
}

Source:
https://openjdk.dev.java.net/svn/openjdk/jdk/trunk/jdk/src/solaris/native/sun/awt/canvas.c

그렇다. Release event 발생시에 몇 가지 조건만 맞으면 click event도 발생된다. AWT native 구현이 크게 다르지 않다면 다른 JRE도 대략 이러한 과정으로 click event를 생성하지 않을까 생각된다.

Posted by roguebean