On Thu, 10 Feb 2022 18:20:40 GMT, Sergey Bylokhov <s...@openjdk.org> wrote:

>> Hello,
>> 
>> Could you please review the following fix for the bug. The bug consists in 
>> the fact that When an assistive technology software by means of Java Access 
>> Bridge API executes "AccessibleAction" "click" on "AccessibleContext" which 
>> corresponds to "javax.swing.JTable" cell containing "javax.swing.JCheckBox", 
>> then the cell's value and cell's view represented by "JCheckBox" stay 
>> unchanged. The issue is a bug in JDK and should be fixed in JDK, because JDK 
>> informs the assistive technology software through Java Access Bridge API in 
>> particular through the function
>> 
>> "BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, 
>> AccessibleActions *actions)"
>> 
>> that "AccessibleContext" of the table cell with "JCheckBox" supports one 
>> action "click", while real execution of this action on this accessible 
>> context does not lead to any result.
>> 
>> THE ROOT CAUSE OF THE BUG:
>> 
>> The reason of the issue is the fact that when the assistive technology 
>> software tries to do "AccessibleAction" on "AccessibleContext" associated 
>> with a cell with boolean data type in "JTable" component through Java Access 
>> Bridge (JAB), the JDK executes this "AccessibleAction" on 
>> "AccessibleContext" of a renderer, which is an instance of the class 
>> "javax.swing.JTable.BooleanRenderer" which is a derivative of "JCheckBox" 
>> class, and the instance of this renderer is single and common for all cells 
>> of boolean data type. Therefore execution of "click" "AccessibleAction" on 
>> this renderer component which is not permanently bound to any particular 
>> cell in the table does not lead to update of the table cell value.
>> 
>> THE FIX:
>> 
>> The fix implements an approach which guarantees setting of new values to the 
>> table's cells with boolean data type on each execution of "AccessibleAction" 
>> of "javax.swing.JTable.BooleanRenderer" instance, when execution of this 
>> action changes the "selected" state of this "BooleanRenderer" JCheckBox 
>> component.
>> 
>> Please take into account that the created automatic regression test 
>> simulates the issue only with Java Accessibility API what is not fully equal 
>> to the original test scenario which requires the assistive technology 
>> software and usage of Java Access Bridge API and which can be tested using 
>> the manual test case attached to the issue in JBS. However the regression 
>> test still allows to reproduce the issue and verify that the fix resolves it.
>> 
>> Thank you,
>> Anton
>
> src/java.desktop/share/classes/javax/swing/JTable.java line 5493:
> 
>> 5491:         }
>> 5492: 
>> 5493:         protected class AccessibleBooleanRenderer
> 
> I guess the doAccessibleAction(i); should work in a similar way as something 
> like "table,getCellJComponent()".click(). Is it actually possible to click on 
> the cell w/o using robot and w/o a11y API just via Swing API and w/o adding 
> code for each type of the renderer?

I do not see the method "getCellJComponent" in JTable or anything like this, 
but what I see in the code is, yes, call to the method "doAccessibleAction(0)" 
of accessible action of accessible context of "JCheckBox" just calls 
"doClick()" method of "JCheckBox". Yes, sure, "doClick()" is the public method 
of any "javax.swing.AbstractButton" and can be called from anywhere having a 
reference to the instance of "javax.swing.AbstractButton".

In the fix I added code to this particular renderer "JTable.BooleanRenderer" in 
order to be able to intercept every invocation of "boolean 
doAccessibleAction(int i)" method of its default "AccessibleAction" 
implementation which is "JCheckBox.AccessibleJCheckBox" and to be able to 
change a boolean value of a cell in "JTable".

I am not going to add any similar code to other types of default table cell 
renderers, because first of all there are not many of them: 
"DefaultTableCellRenderer.UIResource", "NumberRenderer", "DoubleRenderer", 
"DateRenderer", "IconRenderer", "BooleanRenderer", they are used in the method 
"JTable.createDefaultRenderers()", and all of these renderers except for 
"BooleanRenderer" are derivatives of "JLabel" component which reports 0 
supported accessible actions, so any default renderer except of 
"BooleanRenderer" does not support any accessible action. And the problem is 
that "BooleanRenderer" is derivative of "JCheckBox" and therefore it reports to 
the user through Java Access Bridge API, through Java Accessibility API that it 
supports 1 action called "click".

> src/java.desktop/share/classes/javax/swing/JTable.java line 5508:
> 
>> 5506:                     (table != null) && table.isEnabled() &&
>> 5507:                     table.isCellEditable(row, column)) {
>> 5508:                     table.setValueAt(Boolean.valueOf(newSelectedState),
> 
> Where this code is triggered if the user click on the checkbox by the mouse?

Mouse click on JCheckBox is handled differently from execution of "click" 
accessible action on this JCheckBox, because behind mouse click different AWT 
mouse events stand which are processed properly, while "doAccessibleAction()" 
does not involve these mouse events and all their code. So if you are worrying 
about focus or selection as a result of "doAccessibleAction()", then I checked 
the behavior of "doAccessibleAction" on JCheckBox, JButton located outside 
JTable and I confirm that it does not lead to setting of focus to these 
components, hence there is no need to set focus to this "JCheckBox" 
"BooleanRenderer" when it is in table cell and no need to change selection in 
JTable.

I suppose that this code should be invoked only by calling 
"doAccessibleAction(int)" on object of "AccessibleAction" interface either 
through Java Accessibility API like it is in this regression test or through 
Java Access Bridge API from the native assistive software application like it 
is in the manual test attached to the bug and in that case it is called from 
the method "private boolean doAccessibleActions(final AccessibleContext ac, 
final String name)" in the file 
"src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java".

> test/jdk/javax/accessibility/JTable/JCheckBoxInJTableCannotBeClickedTest.java 
> line 92:
> 
>> 90: 
>> 91:     private void createGUI() {
>> 92:         if (!(UIManager.getLookAndFeel() instanceof MetalLookAndFeel)) {
> 
> Why the metal L&F is tested, should at least any default L&F works(like Aqua)?

Hi Sergey! Thank you for review of this fix, I am glad to hear from you. Metal 
L&F is not related anyhow to the bug or the tested scenarios, it is not 
required for the test at all. I used Metal L&F just to make sure that UI of the 
test will be shown in generic way on all OS families on which it will be run, 
what will decrease possibility that it may fail because of other unrelated bug 
connected to some not very well supported L&F. Yes, of course, the test should 
work with any other L&F including Aqua, but I would like to emphasize that this 
bug is about MS Windows OS and requires assistive software native application 
to call "AccessibleAction" of "JTable" cell through Java Access Bridge API. If 
you insist I can remove this code which sets Metal L&F from the test.

-------------

PR: https://git.openjdk.java.net/jdk/pull/7416

Reply via email to