JDK-8036983 : JAB:Multiselection Ctrl+CursorUp/Down and ActivateDescenderPropertyChanged event
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.accessibility
  • Affected Version: 6u45
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows
  • Submitted: 2014-03-10
  • Updated: 2017-05-19
  • Resolved: 2014-07-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
6u81Fixed 7u72Fixed 8u20Fixed 9Fixed
If the key-combination Ctrl+CursorUp/Down is used the event ActivateDescenderPropertyChanged is not passed by JAB. As a consequence, JAWS is unable to recognize the correct active cell. JAWS in turn needs this event to give the corresponding information of the selected cell in Braille or by voice to the user. So, JAWS users have a problem using multi-selection in Swing tables and other Swing objects.

The problem affects Swing classes JTable, JTree (TreeView), JList (Listboxes) and ListView.

A reproducer MultiSelectionTable.jar is attached.

Observed behavior:

SHIFT + CursorDown -> no ActiveDescendentPropertyChanged, but only SelectionChangedEvent  (unexpected behavior)

SHIFT + CursorUp -> 2 events: ActiveDescendentPropertyChanged and SelectionChangedEvent  (expected behavior)

CTRL+CursorDown/Up -> no ActiveDescendentPropertyChanged (unexpected behaviour) (JAWS doesn't send the key-combination to the application. An SR has been opened regarding this issue with Freedom Scientific already.)

CTRL+Space -> 1 event : SelectionChangedEvent (expected behavior)

Expected behavior:

SHIFT + CursorDown -> 2 events: ActiveDescendentPropertyChanged and SelectionChangedEvent

SHIFT + CursorUp -> 2 events: ActiveDescendentPropertyChanged and SelectionChangedEvent

CTRL+CursorDown/Up -> 1 event : ActiveDescendentPropertyChanged

CTRL+Space -> 1 event : SelectionChangedEvent

Attached to the bug is not enough. Manual tests should be put as manual regression tests into regression WS. Otherwise there is no regression test provided.

There are two manual tests case attached.

I do not see any new manual test in the code change. Why does it have reg-manual label?

Ilya, did not get chance to work on the auto test for this one yet. Please see preceding comment in <SQE/> tag for manual test suggestion. Thanks.

The review has been finished. Preparing back ports,

JCK7 JTree/JTable report with fix

Also tested the fix with JCK 7 on Windows, all 64 tests passed. Report attached.

<SQE>Note, for test in JDK 6, need to install JAB 2.0.4 separately from http://jre.us.oracle.com/java/re/accessbridge/2.0.4/, and refer to http://docs.oracle.com/javase/accessbridge/2.0.2/setup.htm for installation instruction. For test in JDK7 and later, JAB 2.0.4 is bundled in Java installer package, no separate install needed</SQE>

<SQE>This bug need manual verification with Ferret, because it requires human interaction during test, detailed test instruction please see attached TreeTest.java and TableTest.java. Another bug JDK-8039978 is filed for further auto-test investigation with Robot and JTReg</SQE>

Test code for JTable

Test code for JTree

Webrev: http://cr.openjdk.java.net/~dmarkov/8036983/jdk9/webrev.00/, out for review

Need to add below function to javax.swing Class JTree.AccessibleJTree, since we would like to fire off the ActiveDescendentPropertyChanged event when focus path on JTree changed (When JTree::setLeadSelectionPath triggered), which covers both selection changed case and focus changed case. Current implementation only covers selection changed scenario, plus, the lead path is not updated properly when using Shift+CursorDown to change selected node. /** * Fire a lead path (focus path) change notification * * @param oldPath - previous lead path * @param newPath - current lead path * */ public void fireActiveDescendantPropertyChange(TreePath oldPath, TreePath newPath) { if(oldPath != newPath) { Accessible oldLSA = (oldPath != null) ? new AccessibleJTreeNode(JTree.this, oldPath, null) : null; Accessible newLSA = (newPath != null) ? new AccessibleJTreeNode(JTree.this, newPath, null) : null; firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, oldLSA, newLSA); } Pete, I guess I need to file a CCC request since it's API change for JTree.AccessibleJTree, do you know which alias I should send the CCC request to?

FVB provided to the customer.

Sure, stuck on build system now, 6u45 always failed when building installer package.

Hi Vivi, When you get done with all your patching and testing you can put your patch in Crucible and assign me, Petr Pchelko, and Sergey Bylokhov as reviewers.

Thanks Pete. No, we don't have to add new methods or make them public, AccessbleJTable can access those selection model through JTable. Just feel they are useful helper functions so thinking it may worth to reveal via helper directly. If we have strict API policy, no new API if not "have to", I will just skip it. Checked the JTree, it has different issue compare to JTable. The DefaultTreeSelectionModel used by JTree did not update the "leadPath" correctly when tree node get selected/deselected. Plus, it only updates the leadPath in the model when the node is selected, but not for node has focus with no selection. So look like leadIndex in JTree does not share exactly same concept as the leadIndex in JTable. Instead, when focus on the tree nodes changed (no selection change), the leadPath in JTree itself will get update. Anyway, testing fix now. Will move to JList one this is done.

Fixed the problem in JTable, need to check JList and JTree. Added two public functions to JTable, not sure what's the policy for adding new API functions in Swing. Need to talk to someone in Dev too. /** * Returns index of row with focus on * * @return index of row with focus on, -1 if no focus */ public int getFocusedRow() { return selectionModel.getLeadSelectionIndex(); } /** * Returns index of column with focus on * * @return index of column with focus on, -1 if no focus */ public int getFocusedCol() { return columnModel.getSelectionModel().getLeadSelectionIndex(); }

Problem is in JTable swing code, the getSelectedRow used to trigger the event always gives the min selected row index, when Shift+Cursor Down is used, the min selected row index does not change, so the event won't be fired as expected.