2014-11-07 4 views
0

EventType 시스템이 JavaFX에서 매우 혼란 스럽습니다. 이 이유는 디자이너가 이벤트 유형 클래스 자체를 일반화하기로 결정했기 때문이라고 생각합니다.Java FX-8 : EventType이 일반적인 이유는 무엇입니까?

실용적인 용도가 있습니까? 아니면형식 안전을 보장하지 않는 형태입니까?

제네릭 형식이 호출 클래스의 어딘가에서 반환되는 경우에만 클래스가 일반화 될 것이라고 생각합니다. 그렇지 않다면 요점은 무엇입니까?

+0

원하는 경우 언제든지 ['Event'] (http://docs.oracle.com/javase/8/javafx/api/javafx/event/Event.html) 하위 클래스를 전송할 필요가 없으므로 메소드에 액세스 할 수 있습니다. –

+0

나는 [lamba expressions] (http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)에서이 기능이 훌륭하다고 가정합니다. [Mary가 약간의 λ를 가지고 있음 - 이벤트 처리를 위해 Java 8 Lambda Expressions 사용하기] (http://learnjavafx.typepad.com/weblog/lambda-expressions/) : * "람다식이 하나의 매개 변수를 가지고 그 유형이 추측하면 괄호는 필요하지 않습니다 "*. –

+0

내 질문에 왜 클래스 EventType 일반입니다. 이 기사에서는 EventHandlers를 완전히 이해하는 이유를 설명합니다. 하지만 왜 EventType입니까 ?? –

답변

6

Event 클래스, 즉 Event의 하위 클래스가 있으며 해당 클래스의 특정 메소드를 정의합니다. 예 : MouseEvent은 이벤트가 발생할 때 마우스의 좌표를 쿼리하는 데 사용할 수있는 다양한 방법을 정의합니다 (getX(), getY(), getSceneX(), getScreenX() 등). ScrollEvent은 스크롤의 양과 방향을 쿼리하는 메소드 인 getDeltaX(), getDeltaY() 등을 정의합니다.

EventType은 어떤 일이 일어 났는지를 지정하는보다 세분화 된 개체입니다. 따라서 EventType 클래스의 상수는 MOUSE_CLICKED, MOUSE_PRESSED, KEY_TYPED, SCROLL_STARTED 등을 포함합니다.이 값들 각각은 특정 Event 서브 클래스와 연관됩니다.

이벤트 등록 방법은 addEventHandler(...)입니다. 이 메서드는 EventType (수신 대기하는 이벤트 유형) 및 EventHandler의 두 매개 변수를 사용합니다. EventHandler은 확실한 이유 때문에 일반적인 것입니다. EventHandler<T extends Event>을 정의하면 해당 이벤트 객체를 취하는 handle(T event) 메서드를 정의 할 수 있습니다.이 메서드를 유형별로 쿼리 할 수 ​​있습니다. (예 : EventHandler<MouseEvent>에는 handle(MouseEvent event) 메서드가 있으며 마우스의 좌표를 쿼리 할 수 ​​있습니다.

이제는 Event 서브 클래스 T과 연결된 EventTypeEventHandler<T>을 등록하는 것이 의미가 있습니다. 게다가, 컴파일러가이를 강제하도록 허용하는 것이 바람직합니다. EventType 클래스를 generic으로 지정하면 컴파일러가이 규칙을 적용하게됩니다. MOUSE_CLICKEDEventType의 인스턴스가 아니라 EventType<MouseEvent>의 인스턴스입니다. addEventHandler(...) 메서드의 서명이 addEventHandler(EventType<T>, EventHandler<T>)이므로 컴파일러는 처리기가 이벤트 유형과 동일한 "이벤트 클래스"에 대해 적용되도록합니다. 당신이 (또는 내가 특히, 형식 유추로 가정) 람다를 사용하여이 결합하면

, 그것은 매우 강력하게 : 특별히 EventType<MouseEvent>입니다

node.addEventHandler(MOUSE_CLICKED, e -> {...}); 

MOUSE_CLICKED 때문에, 컴파일러는 것을 추론 할 수있는 람다에 의해 정의 된 이벤트 핸들러는 EventHandler<MouseEvent>이므로 eMouseEvent입니다. 그래서 컴파일러는 지금

node.addEventHandler(MOUSE_CLICKED, e -> System.out.println(e.getX())); 
node.addEventHandler(KEY_TYPED, e -> System.out.println(e.getText())); 

법적 있음을 추론 할 수 있지만,

node.addEventHandler(MOUSE_CLICKED, e -> System.out.println(e.getText())); 

는 없습니다. EventType이 제네릭이 아닌 경우에는 불가능합니다.

(동일은 람다없는 사실이지만, 덜 간결한 구문뿐만 아니라 포인트 집으로 운전을하지 않습니다. 그러나 EventType 제네릭하지 않고,

node.addEventHandler(MOUSE_CLICKED, new EventHandler<KeyEvent>() { 
    @Override 
    public void handle(KeyEvent event) { } 
}); 

를 거부 할 수있는 컴파일러 방법이 없을 것 다시 MOUSE_CLICKED 유형이 EventType<MouseEvent>이라는 사실은 컴파일되지 않음을 의미합니다.

기술적으로 EventType은 "런타임 유형 토큰"으로 사용됩니다. 관심있는 이벤트뿐만 아니라 이벤트를 처리하는 데 사용해야하는 이벤트 핸들러 유형을 나타내는 데 사용됩니다. 제네릭 사용의 다른 예는 Class<T>입니다 : 간단한 설명은 this part of the Java tutorial을 참조하십시오.

+0

굉장한 설명. 감사. 런타임 유형 토큰과의 병렬 관계는 보이지 않지만 여기에 사용은 컴파일 타임과 런타임이 아닌 것으로 보인다. EventType이 제네릭으로 만들어 졌기 때문에 addEventHandler (EventType , EventHandler ) 메서드에서 람다가 사용되면 컴파일러에서 type 매개 변수를 유추 할 수 있습니다. EventType이 일반적이지 않은 경우 이전 양식 (new EventHandler <유형이 지정됨)을 사용해야합니다. 또는 람다를 사용하면 기본적으로 Event가 유형으로 사용됩니다. 이 기능을 사용하면 제공된 특정 유형의 람다를 사용할 수 있습니까? –

+0

"런타임 유형 토큰"은 다른 엔터티의 런타임 유형을 나타내는 토큰을 의미합니다. 그것은 표준 (또는 정확한) 해석이 아닐 수도 있습니다. 그래서 여기서'EventType' 객체는 이벤트 핸들러의 런타임 타입을 나타내는 토큰입니다. –

+0

람다 사용에만 적용되는 것이 아니라, 'EventHandler' 구현을 사용할 때도 마찬가지입니다. 람다 표현식에 수반되는 향상된 타입 - 추론이 더 명백하게 유용하게 사용된다는 것입니다. 답을 보려면 업데이트를 참조하십시오. –

관련 문제