Event Filtering

Scott Palmer swpalmer at gmail.com
Sat Feb 7 01:45:00 UTC 2015


> On Feb 6, 2015, at 8:21 PM, Tomas Mikula <tomas.mikula at gmail.com> wrote:
> 
>> On Fri, Feb 6, 2015 at 7:33 PM, Scott Palmer <swpalmer at gmail.com> wrote:
>> Is it possible to modify the event in an event filter or otherwise tweak
>> the event that is ultimately received by the target?
>> 
>> <snip>

>>  
>> There are no public constructors for KeyEvents,
> 
> Are we looking at the same Javadoc?
> http://docs.oracle.com/javase/8/javafx/api/javafx/scene/input/KeyEvent.html#KeyEvent-javafx.event.EventType-java.lang.String-java.lang.String-javafx.scene.input.KeyCode-boolean-boolean-boolean-boolean-
> 

No. :-)
I wanted to do this originally with Java 7
The JavaFX 2.2 docs do not list any constructors.

>> 
>> I suppose the 8u40 support for formatted fields is what should be used for
>> my example, but the idea of tweaking the events before they are delivered
>> to an event handler, or synthesizing a new event is more general.  Is it
>> possible?
>> 
>> Scott
> 
> 1. So I think that you can proceed with what you have in mind: consume
> an event and create and fire a new one (with Event.fireEvent(target,
> event)), but I am afraid that is going to mess the order of events.
> Suppose you type JavaFX *really* quickly (or when the UI thread is
> busy with something else). IMO you end up with is JFXAVA instead of
> JAVAFX.

Yeah that would be a problem. I suppose I could be extra clever and remember and consume the 'F' and 'X' events in my filter and then fire new ones after I see my synthesized event come through.
This is starting to smell though.

> 
> 2. You could instead consume the event in the event filter and handle
> it properly yourself, i.e. call textField.replaceSelection() and such.
> (Not very nice, I know, I would not like reproducing TextField's
> behavior.)

Agreed.

> 
> 3. I understand that you don't want some property to ever hold an
> invalid value, but does it have to be the textProperty of the
> textfield?

It just makes things easier to use without the intermediate property and temporary lowercase state on the textProperty, but yes that is one workaround.

> If you set up your data flow like this:
> 
> ObservableValue<String> upper = EasyBind.map(textField.textProperty(),
> String::toUpperCase)
> upper.addListener((obs, oldVal, newVal) -> textField.setText(newVal));
> 
> And then use `upper` wherever you used textField.textProperty()
> before, the rest of your code will never observe any lowercase
> characters.
> 
> 4. Your idea of tweaking an event on its route is interesting, though.
> Let's see if other people have some opinion about that.

Perhaps a new kind of filter could simply return an event if it is meant to be passed on, or return null to prevent it from going any further. Then I would just return a different event than the one that was passed in if I needed to tweak it.
Perhaps returning an array of events would be more appropriate, then one event could cause many downstream events.


Scott


More information about the openjfx-dev mailing list