Testing keyboard events in controls
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.
More information about the openjfx-dev