*   - Cell Traversal: When a cell is in editing mode and the user presses 
"Tab," the subsequent cell should immediately enter editing mode (or Alt+Tab 
the other direction).
  *
- Selective Traversal: The ability to navigate through editable cells while 
skipping read-only cells for example
  *
- Editing Flow: F2 or a double-click should only be required for the initial 
entry into editing mode. Subsequently, the user should be able to navigate 
between cells and edit them directly (with keyboard only).

FYI: it would be trivial for the application to customize the behavior with the 
proposed InputMap [0].

[0] https://github.com/openjdk/jfx/pull/1495

-andy



From: Daniel Peintner <[email protected]>
Date: Wednesday, March 18, 2026 at 04:05
To: Marius Hanl <[email protected]>
Cc: [email protected] <[email protected]>, Andy Goryachev 
<[email protected]>, [email protected] <[email protected]>
Subject: [External] : Re: Re: Re: Re: Allowing a cell to commit the value on 
focus loss

Hi Marius and all,

Thank you for your extensive work on this. Regarding PR #1935, I have had the 
opportunity to test the changes, and the functionality for committing values on 
focus loss appears to be working well.
I would like to share a few common use cases we encounter when working with 
TableView in JavaFX:

- Cell Traversal: When a cell is in editing mode and the user presses "Tab," 
the subsequent cell should immediately enter editing mode (or Alt+Tab the other 
direction).
- Selective Traversal: The ability to navigate through editable cells while 
skipping read-only cells for example
- Editing Flow: F2 or a double-click should only be required for the initial 
entry into editing mode. Subsequently, the user should be able to navigate 
between cells and edit them directly (with keyboard only).

We currently have a solution that "works" (the attached video might give a 
better idea what I mean), but I believe developers often expect this 
functionality to be available out of the box. While PR #1935 is a significant 
step forward, we may want to consider additional features to support these 
specific workflows.

I am interested to hear your thoughts and if others agree that these additions 
would be beneficial.

Best regards,

-- Daniel





On Sat, Nov 15, 2025 at 5:27 PM Marius Hanl 
<[email protected]<mailto:[email protected]>> wrote:
Hey all,

I did a lot of focus tests the last weeks and wrote a big sampler application 
as well.
I will provide the source code as Gist in the PR description at one point.

First of all, things look pretty good! There are some problematic cases, and at 
least one bug from what I can see.
Note: All the problematic cases below also affect all other Controls that 
commit their value on focus loss, like DatePicker, Spinner, ...

What works:
- By default, the focus loss commit works well with all Controls out of the box
- Mnemonics work. They will first request focus before they trigger the action

Problematic cases:
- A Tab selection change is fired before the focus is requested on the TabPane. 
While the focus lost commit still works, it is in my opinion too late. Think 
about disabling a Tab when something in a Table is invalid (which we know after 
the commit)
- List/Tree/Table/View: Selection and focus is changed before the actual cell 
container will receive the focus. Even more weird: For both Tables, the 
selection change is fired BEFORE the focus change. List- and TreeView have the 
correct order. Again, in case we want to disable this Control when another 
Table is invalid, which we know right at the commit, we will still first 
trigger a selection and focus change

Buggy cases:
- As John also mentioned, non focus traversable Controls are completely broken. 
A non focus traversable Button or CheckBox will not request any focus. 
Therefore, Cells, DatePicker, ... can not commit their value. Other Controls 
set to non focus traversable like TextField or the TextField inside the 
DatePicker will request focus, the DatePicker button will not. This seems like 
a bug to me. Could also be something we want to ignore, as we can say: In this 
case, all focus loss commits are broken, so it is up to you. Feedback welcome

Other cases:
- MenuBar, Menu, MenuItem will not trigger focus at all. This might be 
expected. I don't know what to think about that. Feedback welcome

-- Marius
Gesendet: Freitag, 24. Oktober 2025 um 06:58
Von: "Marius Hanl" <[email protected]<mailto:[email protected]>>
An: [email protected]<mailto:[email protected]>, 
[email protected]<mailto:[email protected]>, 
[email protected]<mailto:[email protected]>
Betreff: Re: Re: Re: Allowing a cell to commit the value on focus loss
Those are good points. I will have a look. I do agree that the focus 
traversable behavior is questionable.
I would expect that those problems also exist for Controls like the DatePicker, 
since it does also commit its value on focus loss.

We might not be able to 'fix' mnemonics focus loss, in this case the 
responsibility is indeed an application responsibility.

-- Marius
Gesendet: Mittwoch, 15. Oktober 2025 um 18:52
Von: "John Hendrikx" <[email protected]<mailto:[email protected]>>
An: "Andy Goryachev" 
<[email protected]<mailto:[email protected]>>, "Marius Hanl" 
<[email protected]<mailto:[email protected]>>, 
"[email protected]<mailto:[email protected]>" 
<[email protected]<mailto:[email protected]>>
Betreff: Re: [External] : Re: Allowing a cell to commit the value on focus loss

There is also the focus traversable flag that interacts with this, but perhaps 
there is a bug.  When a button has focusTraversable set to false, clicking it 
will not give it focus.  One may say that a property named "focus traversable" 
would only affect focus *traversal* with the keyboard (as I'd hardly call 
clicking with the mouse "traversal").

That still leaves mnemonic short-cuts and default actions for buttons though.  
Pretty sure those also don't focus the button and aren't intended to, yet do 
execute the action.

--John

On 15/10/2025 17:20, Andy Goryachev wrote:

  *
Buttons are one of those (either with mouse press or keyboard short cut)


This looks like a bug to me, really.  What is the main purpose of the focus 
subsystem?
I know we like to reinvent the wheel, but focus in Swing works as expected, and 
one does get focus lost event on mouse press, and the target button gets the 
focus.  Why should FX be different?

-andy


From: John Hendrikx <[email protected]><mailto:[email protected]>
Date: Wednesday, October 15, 2025 at 08:05
To: Marius Hanl <[email protected]><mailto:[email protected]>, Andy Goryachev 
<[email protected]><mailto:[email protected]>, 
[email protected]<mailto:[email protected]> 
<[email protected]><mailto:[email protected]>
Subject: [External] : Re: Allowing a cell to commit the value on focus loss


Hi Marius,

Focus lost is currently sort of a proxy of starting an interaction with a new 
control, but not all controls gain focus when interacted with.  Buttons are one 
of those (either with mouse press or keyboard short cut), but there is I think 
also the scroll wheel that can interact with a control without focusing it (and 
perhaps even popup menu's).

I can only think of one half-baked solution to this:

- Have a new Event type that is always targetted at the current focus owner 
("InterestLostEvent" ? :))
- This event is automatically fired by Scene just before an event is fired that 
is not targetted at the current focus owner, AND the last event fired did have 
the focus owner as target

What would happen in practice then would be something like:

- User edits field, keypress events go to current focus owner
- User does something else (moves mouse, scrolls, presses a hotkey, or presses 
a button):
    - An InterestLostEvent is fired at the current focus owner BEFORE the new 
event is fired
    - The delayed new event is now fired
    - No further InterestLostEvents are fired until the focus owner has 
received a normal event again
- User goes back to editing after playing with the mouse; events targetted at 
the focus owner renew the interest in that control, and so next time an 
InterestLostEvent is fired again when needed

It feels a bit awkward, especially because simple things like mouse moves may 
trigger it already (but a mouse move may trigger something that requires the 
model to be up to date...); perhaps it would need to be selective in some way 
so one can choose to only be interested in the InterestLostEvent on focus loss 
and mouse clicks.

I can immediately see some problems as well.  Some controls I think allow 
editing without focus gain/loss at all (I think some controls can be edited by 
just scrolling the mouse wheel over them).  When should those controls "commit" 
their values...?

--John



On 15/10/2025 16:39, Marius Hanl wrote:
Hi John,

you are right that there might be corner cases. I hope that we could, what Andy 
suggests, find all cases and have a deeper look at them.
We can also check whether the focus delegation API from Michael is something 
that could help us here (but might be completely unrelated).

The other options as you also mentioned, also have their problems. Even 
debouncing a commit on every keystroke can be unreliable if the user is too 
fast.
I really hope we can make the focus loss reliable, as we then do not need much 
of an API changes inside the Cell Framework.

-- Marius
Gesendet: Montag, 13. Oktober 2025 um 19:32
Von: "Andy Goryachev" 
<[email protected]><mailto:[email protected]>
An: "John Hendrikx" <[email protected]><mailto:[email protected]>, 
"[email protected]"<mailto:[email protected]> 
<[email protected]><mailto:[email protected]>
Betreff: Re: Allowing a cell to commit the value on focus loss
I wonder if we should find out exactly why onFocusLost does not work in these 
cases, as expected.  Then, if I understand the proposal correctly, we won't 
need any API changes.

-andy



From: openjfx-dev 
<[email protected]><mailto:[email protected]> on behalf 
of John Hendrikx <[email protected]><mailto:[email protected]>
Date: Monday, October 13, 2025 at 07:17
To: [email protected]<mailto:[email protected]> 
<[email protected]><mailto:[email protected]>
Subject: Re: Allowing a cell to commit the value on focus loss


Hi Marius,

This may be unrelated, but it may be problematic to rely on committing values 
using focus lost:

I've built a lot of code that relies on focus lost to "commit" values to some 
underlying model.  However, I noticed that a focus lost handler for committing 
values is insufficient when an action is triggered that doesn't trigger a loss 
of focus.   For example, if I have a field "email address" and a Button "Send 
Email", and I have a focus lost handler to commit the email address textfield 
to an underlying model, then pressing the Button will not trigger that handler 
and the underlying model may not have been updated with the latest edits.

Solutions to trigger the correct action are all a bit tricky or annoying:

- Query all fields for their current contents as focus lost is not entirely 
reliable for this purpose
- Have fields update models immediately (which would be on every key press...) 
-- this is not very efficient, and can get in the way of validation / model 
restrictions
- Have controls listen to a "COMMIT" event (this is fired at the current focus 
owner by the Button).  This event may be veto'd if committing the value 
resulted in a validation error, in which case the button press is cancelled

I don't like any of these, but using the last option at the moment because I 
like constant updates and having to requery UI components even less...

--John

I noticed however that if you edit some field (it doesn't have to be in a table 
view, just a regular field), and have a focus lost handler that commits the 
value, that this focus lost handler is insufficient...

On 13/10/2025 14:53, [email protected]<mailto:[email protected]> wrote:
All,

I created an initial poc 1* to support developers to commit the cell value when 
the focus is lost 2* (including 3*).
More specifically, this gives the maximum flexibility to choose what should 
happen when the focus is lost or the editing index changed (which may happen 
when clicking into another cell while editing).
All information mentioned here are also in the description of the PR.

API

- Instead of calling `cancelEdit`, every cell now calls `stopEdit` when the 
focus is lost or the editing index changed. The default behavior is cancelling 
the edit, but developers can now override the behavior and allow a `commitEdit` 
instead
- There are multiple 'events' that can lead to a editing change. Every change 
will now call `stopEdit`.
It is therefore the responsibility of the developer to decide, when it makes 
sense to actually commit the value instead of cancelling it. This decision was 
made as the behavior is manipulating the editing index, but you as a developer 
can as well. We do not really know what intention led to e.g. a change of the 
editing index.
- Every `MOUSE_PRESSED` shifts the focus to the cell container, which is 
undesired in case of editing the cell. So this event is now consumed.
- All `TextField` cells now commit their value (instead of cancel) on focus loss
- `TextField` Escape handling was badly implemented (it was never really 
called, as the cell container handled Escape before)

Considerations

- I tried to make the API minimal, and without breaking changes (other than the 
`TextField` cells committing their values, but we may split this up)
- The Cell Container focus behavior is, well, weird right now. That is why 
consuming the event is needed to better support this PR. One thing we may can 
consider is using the `focusWithin` property instead for all 4 Cell Containers 
and not calling `requestFocus` for nearly every `MOUSE_PRESSED` event. If we 
decide so, this is needs to be done before merging this PR.
- Clicking the `ScrollBar` now commits/cancels the edit. I checked other 
applications and this is very common. But something I need to note here. This 
probably can be fixed in the same way mentioned above (`focusWithin`)
- It might be hard for a developer to exactly know the cause why `stopEdit` is 
called. This does not seem like a problem, as e.g. for a `TextField`, you 
normally register listeners for e.g. pressing the Escape key on it, so you keep 
full control.

Another Approach

- Another Approach I tested could be to request the focus to a cell when 
clicked/edited, to ensure that the focus listener is ALWAYS called before 
another cell will reach the editing state. Again, we probably need to change 
the focus handling to e.g. use the `focusWithin` property. With this approach, 
we can only call `stopEdit` when the focus changed (since it is now called 
always), but not when the editing index changed.

1* - 
https://github.com/openjdk/jfx/pull/1935<https://urldefense.com/v3/__https://github.com/openjdk/jfx/pull/1935__;!!ACWV5N9M2RV99hQ!KeaTwOLaODiie2jQZ01j-vH00U9_nZNV8YxV6B0SXCExWnLFky0svIofyVK0ZPt0xawAISlouP_NCkqvMwFhYVHnQZte$>
2* - https://bugs.openjdk.org/browse/JDK-8089514
3* - https://bugs.openjdk.org/browse/JDK-8089311

-- Marius

Reply via email to