RFR: 8209788: Left/Right/Ctrl+A keys not working in editor of ComboBox if popup showing [v8]

Ambarish Rapte arapte at openjdk.java.net
Mon Sep 7 13:38:21 UTC 2020

On Tue, 1 Sep 2020 13:59:06 GMT, Ambarish Rapte <arapte at openjdk.org> wrote:

>> hmm .. this is getting unwieldy, isn't it ;)
>> The pain points:
>> - cascade of listeners (editable -> comboSkin -> properties -> behavior)
>> - dynamic change (add/remove) of mappings
>> - multiple key/value pairs for basically the same - though variant - state
>> My suggestion would be to take a step back (in solution path): near the beginning was the evaluation of using different
>> inputMaps for different state contexts. Which was not further evaluated because it looked like we could get away with
>> simply configuring the mappings - based on certain condition - once at instantiation time. Which has the advantage of
>> not touching too much code but unfortunely turned out to be not enough.   Meanwhile, I'm convinced that in the long run
>> there is no way around different inputMaps based on context: the differences in behavior (stand-alone vs. editable
>> combo-popup vs. not-editable combo-popup) are many - f.i. focus-only navigation doesn't make sense in the popup (should
>> be selection navigation always), left/right in a not-editable should trigger selection navigation .. and certainly
>> more. So we not only have to enable/disable certain mappings, but also re-map the triggered behavior.   That's too
>> broad for this issue, but we could take a step into that direction: use the InputMap/Mapping API to help - it was
>> designed for exactly such a differentiation :) The step would be to use interceptors (instead of dynamic modification
>> of the mappings list), they are available on both inputMap and mapping level. As a first step, we could use the latter:
>> keep the addition of mappings as-is (before the fix) and add interceptors to mappings for inclusion/exclusion based on
>> context. No listeners, no dynamic modification, just one marker in the properties .. hopefully :)  Raw code snippets:
>>     // let combo skin put a Supplier for editable as value
>>     getProperties().put("comboContext", (Supplier<Boolean>) () -> getSkinnable().isEditable());
>>     // let listView behavior use the supplier to build interceptors
>>     Supplier<Boolean> comboEditable = (Supplier<Boolean>) control.getProperties().get("comboContext");
>>     Predicate<KeyEvent> interceptIfInCombo = e -> comboEditable != null;
>>     Predicate<KeyEvent> interceptIfInEditableCombo = e -> comboEditable != null && comboEditable.get();
>>     if (comboEditable == null) {
>>         // add focus traversal mappings if not in combo popup
>>         addDefaultMapping(listViewInputMap, FocusTraversalInputMap.getFocusTraversalMappings());
>>     }
>>     // add mappings with appropriate interceptors
>>     addDefaultMapping(listViewInputMap,
>>         // missing api in KeyMapping: no constructor taking KeyCode and interceptor
>>         new KeyMapping(new KeyBinding(HOME), e -> selectFirstRow(), interceptIfInEditableCombo),
>>         new KeyMapping(new KeyBinding(END), e -> selectLastRow(), interceptIfInEditableCombo),
>>         new KeyMapping(new KeyBinding(HOME).shift(), e -> selectAllToFirstRow(), interceptIfInCombo),
>>         new KeyMapping(new KeyBinding(END).shift(), e -> selectAllToLastRow(), interceptIfInCombo),
>>         ...
>> With this, the tests for key navigation are passing, the low-level mapping tests will have to be re-formulated to test
>> for not/intercepted vs. existence.
>> What do you think?
>> What do you think?
> Suggestion looks promising, I shall try it and update.

@kleopatra  @kevinrushforth
Change looks pretty with interceptor.
Please take a look.


PR: https://git.openjdk.java.net/jfx/pull/172

More information about the openjfx-dev mailing list