GWT 맞춤 이벤트
사용자 지정 GWT 이벤트 처리기가 작동하는 방식을 이해하는 데 문제가 있습니다. 나는 주제에 대해 꽤 많이 읽었고 여전히 안개가 낀다. 이 GWT Custom Event Handler 와 같은 Stackoverflow에서 스레드를 읽었습니다 . 누군가 다음과 같은 적용 마나에서 설명 할 수 있습니다.
나는 한 블록에 2 개의 클래스와 남자 클래스가 있습니다. 남자가 블록과 충돌하면 남자는 이벤트 (onCollision ())를 발생시키고 블록 클래스는 해당 이벤트를 수신합니다.
감사
일반적인 이벤트 :
이벤트는 항상 무언가에 대해 알리기 위해 전송됩니다 (예 : 상태 변경). 남자와 벽에 대한 예를 들어 봅시다. 여기서 우리는 사용자가 미로에서 사람처럼 걸을 수있는 게임이 있다고 상상할 수 있습니다. 사용자가 벽에 부딪 힐 때마다 충돌에 대해 알려야 반응 할 수 있습니다 (예 : 벽이 파괴 된 벽으로 렌더링 될 수 있음). 이는 벽과의 충돌이 감지 될 때마다 충돌 이벤트를 전송함으로써 가능합니다. 이 이벤트는 사람에 의해 전송되고 이벤트에 관심이있는 시스템의 모든 개체가이를 수신하고 그에 따라 반응 할 수 있습니다. 이벤트를 받고자하는 객체는 이벤트에 관심이있는 것으로 등록해야합니다.
이것이 이벤트가 모든 시스템 또는 프레임 워크에서 일반적으로 작동하는 방식입니다 (GWT뿐만 아니라). 이러한 시스템에서 이벤트를 보내고 받으려면 다음을 정의해야합니다.
- 전송되는 항목 (이벤트는 어떻게 표시됩니까)
- 이벤트를받는 사람 (이벤트 수신기)
- 이벤트를 보내는 사람 (이벤트 보낸 사람)
그런 다음 다음을 수행 할 수 있습니다.
- 이벤트 수신을 원하는 이벤트 수신자 등록
- 이벤트 보내기
GWT의 이벤트 :
여기에서는 GWT에서 커스텀 이벤트를 사용하는 예를 보여 드리겠습니다. 우편함 확인을 담당하는 시스템의 예를 사용하여 새 메일이 있으면 사용자에게 알려 드리겠습니다. 시스템에 최소 2 개의 구성 요소가 있다고 가정 해 보겠습니다.
- 사서함을 확인하는 메시지 검사기 및
- 새 메일을 표시하는 메시지 표시기
메시지 검사기는 새 메일이 수신되고 메시지 표시기가 이러한 이벤트를 수신 할 때 이벤트를 보냅니다.
1 단계 : 이벤트 정의
새 메일에 대한 정보는 MessageReceivedEvent
클래스 의 인스턴스로 전송됩니다 . 클래스에는 새 메일이 포함되어 있습니다 (단순화를 위해라고 가정하겠습니다 String
).
이 클래스의 전체 소스 코드는 다음과 같습니다 (소스 코드 아래에 주석이 있습니다).
public class MessageReceivedEvent extends GwtEvent<MessageReceivedEventHandler> {
public static Type<MessageReceivedEventHandler> TYPE = new Type<MessageReceivedEventHandler>();
private final String message;
public MessageReceivedEvent(String message) {
this.message = message;
}
@Override
public Type<MessageReceivedEventHandler> getAssociatedType() {
return TYPE;
}
@Override
protected void dispatch(MessageReceivedEventHandler handler) {
handler.onMessageReceived(this);
}
public String getMessage() {
return message;
}
}
MessageReceivedEventHandler
이벤트 수신기를 나타내는 인터페이스입니다. 지금은 신경 쓰지 마십시오. 나중에 논의 할 것입니다.
GWT 이벤트를 나타내는 모든 클래스는 클래스를 확장해야 GwtEvent
합니다. 이 클래스에는 구현해야하는 두 개의 추상 메서드 getAssociatedType
및 dispatch
. 그러나 모든 이벤트 클래스에서 일반적으로 매우 유사한 방식으로 구현됩니다.
클래스는 수신 된 메시지에 대한 정보를 저장합니다 (생성자 참조). 모든 이벤트 수신자는 getMessage
메소드를 사용하여 가져올 수 있습니다 .
2 단계 : 이벤트 수신기 정의
GWT의 각 이벤트 유형은이 이벤트 유형의 수신자를 나타내는 인터페이스와 연관됩니다. GWT에서 수신기는 핸들러라고합니다. 예에서 이벤트 수신기 인터페이스의 MessageReceivedEvent
이름은으로 지정 MessageReceivedEventHandler
됩니다. 소스 코드는 다음과 같습니다.
public interface MessageReceivedEventHandler extends EventHandler {
void onMessageReceived(MessageReceivedEvent event);
}
각 핸들러는 EventHandler
인터페이스 를 확장해야 합니다. 또한 이벤트가 발생할 때 호출 될 메소드를 정의해야합니다 (최소 하나의 매개 변수-이벤트를 가져야 함). 여기서 메서드 이름은 onMessageReceived
. 각 수신자는이 메소드를 구현하여 이벤트에 반응 할 수 있습니다.
예제에서 유일한 이벤트 수신기는 다음과 MessageDisplayer
같습니다.
public class MessageDisplayer implements MessageReceivedEventHandler {
@Override
public void onMessageReceived(MessageReceivedEvent event) {
String newMessage = event.getMessage();
// display a new message
// ...
}
}
3 단계 : 이벤트 발신자 정의
예제에서 유일한 이벤트 발신자는 메일 확인을 담당하는 구성 요소입니다 EventChecker
.
public class MessageChecker implements HasHandlers {
private HandlerManager handlerManager;
public MessageChecker() {
handlerManager = new HandlerManager(this);
}
@Override
public void fireEvent(GwtEvent<?> event) {
handlerManager.fireEvent(event);
}
public HandlerRegistration addMessageReceivedEventHandler(
MessageReceivedEventHandler handler) {
return handlerManager.addHandler(MessageReceivedEvent.TYPE, handler);
}
}
모든 이벤트 발신자는 HasHandlers
인터페이스 를 구현해야 합니다.
여기서 가장 중요한 요소는 HandlerManager
필드입니다. HandlerManager
이름에서 알 수 있듯이 GWT에서는 이벤트 처리기 (이벤트 수신기)를 관리합니다. 처음에 언급했듯이 이벤트를 수신하려는 모든 이벤트 수신자는 자신을 관심으로 등록해야합니다. 이것이 핸들러 관리자를위한 것입니다. 이벤트 핸들러를 등록하고 등록 된 모든 이벤트 핸들러에 특정 이벤트를 보낼 수 있습니다.
a HanlderManager
가 생성 되면 생성자에서 하나의 인수를받습니다. 모든 이벤트에는 원본 소스가 있으며이 매개 변수는이 핸들러 관리자가 보내는 모든 이벤트의 소스로 사용됩니다. 예제에서는 this
이벤트 소스가 MessageChecker
입니다.
이 메서드 fireEvent
는 HasHandlers
인터페이스에 정의되어 있으며 이벤트 전송을 담당합니다. 보시다시피 핸들러 관리자를 사용하여 (발동) 및 이벤트를 보냅니다.
addMessageReceivedEventHandler
이벤트 수신자가 이벤트 수신에 관심이있는 것으로 등록하는 데 사용됩니다. 다시 핸들러 관리자가이를 위해 사용됩니다.
4 단계 : 이벤트 보낸 사람과 이벤트 수신기 바인딩
모든 것이 정의되면 이벤트 수신자는 이벤트 발신자에 등록해야합니다. 이 작업은 일반적으로 객체 생성 중에 수행됩니다.
MessageChecker checker = new MessageChecker();
MessageDisplayer displayer = new MessageDisplayer();
checker.addMessageReceivedEventHandler(displayer);
이제에서 보낸 모든 이벤트 checker
가에서 수신됩니다 displayer
.
5 단계 : 이벤트 보내기
이벤트를 보내 MessageChecker
려면 이벤트 인스턴스를 만들고 fireEvent
메서드를 사용하여 보내야합니다 . 이 지팡이는 newMailReceived
방법 으로 수행 할 수 있습니다 .
public class MessageChecker implements HasHandlers {
// ... not important stuff omitted
public void newMailReceived() {
String mail = ""; // get a new mail from mailbox
MessageReceivedEvent event = new MessageReceivedEvent(mail);
fireEvent(event);
}
}
나는 그것이 명확하고 도움이되기를 바랍니다. :)
이 질문과 Piotr GWT의 답변 이후로 사용자 지정 이벤트를 생성하는 약간 다른 방법에 대한 지원이 추가되었습니다. 이 이벤트 구현은 패키지에서 GWT의 EventBus와 함께 사용할 특정 빌드 com.google.web.bindery.event.shared
입니다. GWT 2.4 용 맞춤 이벤트를 빌드하는 방법에 대한 예 :
import com.google.web.bindery.event.shared.Event;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.HandlerRegistration;
/**
* Here is a custom event. For comparison this is also a MessageReceivedEvent.
* This event extends the Event from the web.bindery package.
*/
public class MessageReceivedEvent extends Event<MessageReceivedEvent.Handler> {
/**
* Implemented by methods that handle MessageReceivedEvent events.
*/
public interface Handler {
/**
* Called when an {@link MessageReceivedEvent} event is fired.
* The name of this method is whatever you want it.
*
* @param event an {@link MessageReceivedEvent} instance
*/
void onMessageReceived(MessageReceivedEvent event);
}
private static final Type<MessageReceivedEvent.Handler> TYPE =
new Type<MessageReceivedEvent.Handler>();
/**
* Register a handler for MessageReceivedEvent events on the eventbus.
*
* @param eventBus the {@link EventBus}
* @param handler an {@link MessageReceivedEvent.Handler} instance
* @return an {@link HandlerRegistration} instance
*/
public static HandlerRegistration register(EventBus eventBus,
MessageReceivedEvent.Handler handler) {
return eventBus.addHandler(TYPE, handler);
}
private final String message;
public MessageReceivedEvent(String message) {
this.message = message;
}
@Override
public Type<MessageReceivedEvent.Handler> getAssociatedType() {
return TYPE;
}
public String getMessage() {
return message;
}
@Override
protected void dispatch(Handler handler) {
handler.onMessageReceived(this);
}
}
이벤트는 다음과 같이 사용됩니다.
이 이벤트에 대한 핸들러를 eventbus에 등록하려면 MessageReceivedEvent 클래스에서 정적 등록 메소드를 호출하십시오.
MessageReceivedEvent.register(eventbus, new MessageReceivedEvent.Handler() {
public void onMessageReceived(MessageReceivedEvent event) {
//...do something usefull with the message: event.getMessage();
}
});
이제 fireEvent
새로 생성 된 이벤트 를 사용하여 eventbus 호출 에서 이벤트를 시작합니다.
eventBus.fireEvent(new MessageReceivedEvent("my message"));
다른 구현은 GWT의 자체 EntityProxyChange
이벤트 클래스 에서 찾을 수 있습니다 . 이 구현은 EventBus의 대체 옵션을 사용합니다. 를 통해 특정 소스에 바인딩 addHandlerToSource
되고을 통해 트리거 될 수있는 핸들러를 추가하는 기능을 사용합니다 eventBus.fireEventFromSource
.
The event implementation given here is also more suitable when working with GWT's Activities.
I created my own widget by extending GWT's Composite class. I wanted to create my own custom event in this class. I wanted the events to be accessible to GWT's WindowBuilder Editor.
I learned a lot of from the answers on this page, but I had to make some changes.
I wanted to start from the Hilbrand Bouwkamp answer, because it was newer. But I ran into a couple of problems. 1) That answer made reference to the event bus. The even bus is a global variable owned by the main program. It's not clear how a widget library could get access to that. 2) I wasn't starting from scratch. I was was extending GWT library code. In order to make that work, I had to start from the GwtEvent class, rather than the Event class.
Piotr's answer is essentially correct, but it was very long. My class (indirectly) extends GWT's Widget class. Widget takes care of many details, such as creating a HandlerManager object. (I looked through the source code, and that's exactly how standard Widgets work, not by using an EventBus.)
I only had to add two things to my widget class to add a custom event handler. Those are shown here:
public class TrackBar extends Composite {
public HandlerRegistration addValueChangedHandler(TrackBarEvent.Handler handler)
{
return addHandler(handler, TrackBarEvent.TYPE);
}
private void fireValueChangedEvent()
{
final TrackBarEvent e = new TrackBarEvent(value);
fireEvent(e);
}
My new event is almost exactly the same as Piotr's event class, shown above. One thing is worth noting. I started with getValue(), based on that example. Later I added getTrackBar() to give a lot more information. If I was starting from scratch I'd focus on the latter, not the former. The complete event class is shown below.
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
public class TrackBarEvent extends GwtEvent< TrackBarEvent.Handler >
{
public interface Handler extends EventHandler {
void onTrackBarValueChanged(TrackBarEvent event);
}
static final Type<TrackBarEvent.Handler> TYPE =
new Type<TrackBarEvent.Handler>();
private final int value;
public TrackBarEvent(int value) {
this.value = value;
}
@Override
public Type<TrackBarEvent.Handler> getAssociatedType() {
return TYPE;
}
public int getValue() {
return value;
}
public TrackBar getTrackBar()
{
return (TrackBar)getSource();
}
@Override
protected void dispatch(Handler handler) {
handler.onTrackBarValueChanged(this);
}
}
If you happen to be using the GWTP framework on top of GWT, refer to this Stack.
GWTP is "A complete model-view-presenter framework to simplify your next GWT project."
참고URL : https://stackoverflow.com/questions/2951621/gwt-custom-events
'development' 카테고리의 다른 글
StyleCop에서 "this"를 접두사로 사용하는 방법 또는 속성 호출을 권장하는 이유는 무엇입니까? (0) | 2020.11.09 |
---|---|
성능 문제 : Java vs C ++ (0) | 2020.11.09 |
Bash는 다른 디렉토리 컨텍스트에서 어떻게 명령을 실행할 수 있습니까? (0) | 2020.11.09 |
외래 키가있는 열 삭제 Laravel 오류 : 일반 오류 : 1025 이름 바꾸기 오류 (0) | 2020.11.09 |
jQuery에서 요소로 스크롤하는 방법은 무엇입니까? (0) | 2020.11.09 |