JavaFX / TreeTableView: Relationship between Selection and Focus - javafx

I need some clarification on the relationship between Focus and Selection in javafx.scene.control.TreeTableView.
In my code I have defined:
ttvMainTree.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
Assumption 1: I was assuming, that the focused item is always the last item with left-click. Also I was assuming that the a left-click always moves the selection. So that in SelectionMode.SINGLE the focused item and the selected item are always identical.
This seemed to be correct in 90% of all situations. Anyhow after some random left-clickes my code produced such a picture:
Kindly confirm:
The item with the blue background is the selected item
The item with the blue border ist the focused item
Here the focused item can be changed with left-click, the selected item seems to be not influenced by left-click.
My apologies for not providing an SSCCE. At the moment I don't know how to shorten my code and reproduce this behavior.
Therefore a general question:
What is wrong with assumption 1?

In my humble opinion, i don't think there is a difference on the behavior of the two, it is rather a relationship as you said, when you select a Node, this one request the focus.
The focus can be controlled with the "focusTraversable" :
focusTraversable : Specifies whether this Node should be a part of focus traversal cycle. When this property is true focus can be moved to this Node and from this Node using regular focus traversal keys.
For your case I think maybe it's because you have chosen a TreeTableView that is both child and parent Child 2 !

Found the reason for the odd behaviour of my application:
A selection listener caused update of the datamodel. Basically the list with child-elements was deleted an populated again with the same data. This caused confusion in the selection model.

Related

How to figure out the index of a ToggleGroup's selected toggle?

I'm trying to select an item from a list that's sorted the same way as a ToggleGroup I have besides it. However, I found that toggleGroup.getToggles().indexOf(toggleGroup.getSelectedToggle()) always returns -1 (visible in the IndexOutOfBoundsException thrown as I pass it). Is there another way of figuring out the index, or am I at a loss with my approach and need to figure out something completely different?
UPDATE: Apparently, for the first time an item is selected (I have this code attached to changes of selectedToggleProperty()), it works fine (I just get no notice of it because the elements I make visible have no proper layout). However, when an item is selected while another item already is selected, getselectedToggle() becomes null, causing aforementioned behavior.
All of the JavaFX toggle controls have a property called UserData. You should use that to create the links between the toggles and data list. Relying on the index of the toggles in the toggle group is probably a bad idea.

How to make a section show the selected row's information?

I have got an UI with two sections.
The first section contains a repeat grid layout.
The last one is a section with detailed information about selected grid's row.
I need to provide a feature to select rows using "Up" and "Down" keys (press "Up" - one element above, "Down" - one bellow). And the section with information must be refreshed.
I managed to develop a feature of focusing leveraging Up/Down keys.
But I have got an interesting bug: the next row is selected, but the section is refreshed and show info about previous row.
Here is an example of the actiion configuration:
The issue is still unresolved.
Create action set "focus" on the list item and set refresh section there. Refresh should happen on focus on next row.
I struggled to find out an out-of-box solution, but I realized that Pega doesn't provide any.
My bug happens because the section refreshes when the previous element is selected.
And after refreshing it jumps to the next element. I performed many variants and found out that I can't change the order.
The only way to provide this is to code custom handler.

ListView single selection change and drag event

I'm trying to understand sequencing of property changes and mouse events inside ListView.
To detect a change is there a difference between observing selectedIndex vs selectedItem?
To drag and drop ListView items is there any difference between registering onDrag.. events against ListView vs each ListCell?
Is there any scenario where a "onDragDetected" event would be received before the selection model (which I'm observing) is updated?
Thanks
To detect a change is there a difference between observing
selectedIndex vs selectedItem?
Not really; I think this is just a matter of whichever is the most convenient for you to use.
To drag and drop ListView items is there any difference between
registering onDrag.. events against ListView vs each ListCell?
I would advocate for registering with the ListCell. There's no direct way to check a mouse event on the ListView and then determine which cell the mouse event occurred on. You would have to fall back on the selected item, and that's not really semantically the same thing. (For example, how would you handle drag on empty cells, which wouldn't change the selection...?)
Is there any scenario where a "onDragDetected" event would be received
before the selection model (which I'm observing) is updated?
That's implementation dependent. I think the current implementation uses a mousePressed event to handle selection (though I'm not certain), so it should trigger before the drag is detected, but do you really want to rely on that implementation not changing in a future release?
IMHO, relying on the selected item just feels wrong here. It's semantically different to what you want: you actually want to know "which item the user clicked on", not "which item is selected". Sure, the two are related, but they're not the same thing, so in a way you'd be introducing a dependency on the selection API that should be independent of the thing you're trying to achieve. That is most definitely an opinion, though. Your mileage may vary...

how to handle WAI ARIA role="listbox"

I have a list of options from which one can be selected. For all intents and purposes HTML's <select> element covers this. Since we need a different visual presentation, I'm looking at using WAI ARIA role="listbox". I'm unclear on how to use aria-activedescendant, aria-selected and aria-checked.
Questions regarding focus/active state:
If I use aria-activedescendant on the listbox to point to the [role="option"] that is currently active (has "virtual focus"), I would use [aria-selected]. How would best I tell the option element itself that it is active (has "virtual focus") to represent that visually? (:focus is on the listbox, after all)
an [role="option"] can have [aria-checked] and [aria-selected]. I guess I need [aria-selected] but don't see what I'd use [aria-checked] for.
Is there a trick to avoid having to put IDs on every option simply so it can be referenced by aria-activedescendant?
Questions regarding keyboard interaction:
"Checkbox - Space toggles checkboxes, if the list items are checkable" - how do I figure out if they are checkable or selectable?
Questions regarding validation:
If the listbox has [aria-required="true"] some sort of validation has to be performed. specifically if an option has been selected (or checked).
when do I trigger the validation? is on blur sufficient?
when invalid, what do I have to do besides setting [aria-invalid="true"] on the listbox?
aria-checked is indeed more something for a list of very closely related options with actual visible checkboxes that can be toggled on or off. This is most common in the Windows world. Explorer can be set to such a pseudo multi-select mode, or some apps use that to activate or deactivate a set of accounts. On the Mac, you can think of the list of accounts in Adium, which can be either checked (active) or not. A selection will always be there, and one or more of their checkboxes can be checked or not.
aria-selected is always the right one to indicate the selected state of an option. E. g. when traversing the list with the arrow keys, aria-selected="true" moves from item to item, while the others must then get aria-selected="false". As Patrick said, you can use this to also generate some nice looking CSS.
As for keyboard interaction: arrows up and down will select an item, and if the items are checkable, too, space will toggle the checked or unchecked state of the currently selected item.
In a true multi-select, like html:select #size>1, and multiselectable being true, the interaction would be:
Arrow keys select a single item.
Ctrl+Arrow keys would move focus from item to item, but not select the item yet.
Ctrl+Space would select the item.
Shift+up and down arrows would select contiguous items.
This is, again, standard Windows paradigm, can be observed in Explorer in Details view, for example.
As for validation: onBlur is sufficient, or you could dynamically do it via changes in selection/focused item, make sure at least one item is selected, or whatever validation you need.
aria-invalid="true" is sufficient for screen readers to know, but an error message and possibly a visual indication would be nice for everyone to know what's wrong.
How would best I tell the option element itself that it is active (has "virtual focus") to represent that visually?
Generally, you'd add aria-selected="true" and then craft some CSS that takes care of it using attribute selectors, e.g. div[role=option][aria-selected=true] { ... }, or add a css class dynamically?
[aria-checked] and [aria-selected]
This is more of a philosophical question I guess. aria-selected more closely matches what you'd have with a select...but then again (particularly for multi-select widgets) you can imagine the listbox actually being a series of checkboxes, and in that case you'd use aria-checked. there's no definitive right or wrong about either one (something you'll find a lot once you dive into more complex ARIA widgets).
Is there a trick to avoid having to put IDs on every option simply so it can be referenced by aria-activedescendant
Hmm...perhaps you could dynamically generate IDs for all options on page load via script? Or - but not tested - you could have something like a "roving" ID that moves around the options depending on which one is active (adding/removing the ID to the relevant option).

How to find the first focusable component in a container?

I'm trying to programatically set a focus on the first component of a given container. What's the best way to do it?
A couple of notes:
I haven't found any appropriate method on IFocusManager / IFocusManagerContainer interfaces. Ideally, there would be IFocusManagerContainer#getFirstFocusableComponent() but there is no such method.
The "first" component is the one that would receive focus if you were on some component just before the container and pressed TAB. It is not necessarily the first focusable child of the container (tab order plays role here).
I'd like the solution to perform well. I'm not particularly keen on traversing display list, I still hope there is some better way.
Thanks!

Resources