Testing keyboard events in controls

Jonathan Giles jonathan.giles at oracle.com
Tue Jan 3 22:03:18 PST 2012

Hi all (and happy new year!),

ListView/TreeView/TableView have a heap of keyboard requirements that 
come in from UX. Keyboard event handling code is often fraught with 
complexity due to the many permutations. I'm frequently getting burnt 
due to subtle changes in this code causing unintended regressions.

I finally decided to do something about this, and have thrown together a 
very simple set of APIs to make it possible to write simple unit tests 
that test keyboard navigation. It's all very lightweight so that it can 
easily run as part of the JavaFX engineering continuous build (which 
means it fails sooner, compared to SQE tests, or even worse - when it 
ends up in the hands of developers!). Additionally, it's all very 
primitive and proof-of-concept at this stage, and I am happy to refine 
(and relocate) the class to provide utility in this area if it doesn't 
duplicate existing functionality I'm unaware of. I'm also certain I'm 
missing some of the details on how best to do this, so feedback is welcome.

Anywho, you can find the class in the rt/javafx-ui-controls project, in 
the test directory, in javafx.scene.control.KeyEventFirer. You can see a 
few unit tests that were used to flesh out the API in 
javafx.scene.control.ListViewKeyInputTest. I plan to add many more here, 
and for other controls, in the coming weeks and months.

These are the key pointers:
1) When creating a KeyEventFirer, you must provide an EventTarget. 
Despite the scary name, all Nodes are EventTargets.
2) I put the ListView inside a group, which is placed in a scene, which 
itself is placed in a stage. I show() and hide() the stage as necessary 
(in the setup() / tearDown() methods). Without this, events don't fire.
3) I use the separate javafx.scene.control.KeyModifier class to provide 
zero or more keyboard modifiers (shift, alt, ctrl, meta) to the keyboard 
input. An enum might already exist for these modifiers, but I'm not sure...
4) I have convenience methods (for my needs, anyway) for 
up/down/left/right keyboard inputs, in the form of 
'do*ArrowPress(KeyModifier... modifiers)' methods. I'm sure more can be 
5) For all other keyboard input, you can use the 'doKeyPress(KeyCode 
keyCode, KeyModifier... modifiers)' method.

Any feedback would be appreciated.

-- Jonathan

More information about the openjfx-dev mailing list