4

I am reading the JavaFX 11 Node API and can't understand why EventHandler often uses generics, as in <? super Event>.

For example:

Node.setOnKeyPressed(EventHandler<? super KeyEvent> value)

why not simply

Node.setOnKeyPressed(EventHandler<KeyEvent> value)

Could anyone explain this?

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
Pavel_K
  • 10,748
  • 13
  • 73
  • 186
  • `EventHandler` has a single method - `handle(T)`. There is no reason to require that `T` is a `KeyEvent` - any handler that can handle a `KeyEvent` will do. For example, an `EventHandler` would do, because all `KeyEvent`s are also `Event`s. As with all (appropriate) usages of wildcards, it makes the API a bit more flexible. – Andy Turner Jan 19 '19 at 10:56
  • @AndyTurner Thank you for your explanation. But I ask you to remove `duplicate` as the main idea of this question is when/in what cases do we need `API a bit more flexible`. – Pavel_K Jan 19 '19 at 11:18
  • For a contrived example, say you wanted to count how many times a node receives input. Instead of duplicating code you create a single `EventHandler`. But for some reason you decide to only count key pressed events for some arbitrary node. Because of the generic signature you could call `setOnKeyPressed` with your `EventHandler`. Otherwise, you'd have to create a wrapper and filter out non-key-pressed events and delegate. – Slaw Jan 19 '19 at 11:36
  • Personally, it'd be _less understandable_ if the API _didn't_ provide this flexibility. Even if the designers at the time couldn't think of use cases, that doesn't mean application developers couldn't. Imagine if you wanted the flexibility and it wasn't there? Having the flexibility doesn't inconvenience anyone, whereas not having the flexibility might. – Slaw Jan 19 '19 at 11:40
  • @Pavel_K "when/in what cases" consider using wildcards for method parameters *pretty much* always, at least in public APIs. The only reason not to use them is if the syntax becomes unduly burdensome. See *Effective Java* (for example) for an in-depth discussion. – Andy Turner Jan 19 '19 at 11:43
  • @Slaw Thank you very much for your explanation. – Pavel_K Jan 19 '19 at 11:47
  • @Pavel_K "the only reason" the other reason is if you actually need the invariance, e.g. you want a list to both produce and consume in the same method (`List` is the intersection of `List extends T>` and `List super T>`). – Andy Turner Jan 19 '19 at 11:51
  • @Slaw BTW could you say - can we add multiple event handlers to one node. For example this way: `buttonFoo.setOnKeyPressed(inputEventHandler); buttonFoo.setOnKeyPressed(keyPressedHandler);`? – Pavel_K Jan 19 '19 at 11:51
  • Not via the `onXXX` properties. Setting those properties will replace the previous value. You could do it via `addEventHandler`, however. – Slaw Jan 19 '19 at 11:54
  • @Slaw Thanks a lot. – Pavel_K Jan 19 '19 at 11:55
  • @AndyTurner I understood your idea. Thank you for your comments. – Pavel_K Jan 19 '19 at 12:03

0 Answers0