Repository: nvaccess/nvda

Issue:
NVDA does not announce the non-editable state of a non-editable JTextField (Java Access Bridge)
<!-- Please read the text in this edit field before filling it in.
Please thoroughly read NVDA's wiki article on how to fill in this template, including how to provide the required files.
Issues may be closed if the required information is not present.
https://github.com/nvaccess/nvda/blob/master/devDocs/githubIssueTemplateExplanationAndExamples.md
Please also note that the NVDA project has a Citizen and Contributor Code of Conduct which can be found at https://github.com/nvaccess/nvda/blob/master/CODE_OF_CONDUCT.md. NV Access expects that all contributors and other community members read and abide by the rules set out in this document while participating or contributing to this project. This includes creating or commenting on issues and pull requests. 

Each of the questions and sections below start with multiple hash symbols (#). Place your answers and information on the blank line below each question.
-->
When moving the keyboard focus to a non-editable JTextField, NVDA does not announce that this JTextField is not editable, although this information is transmitted via the Java Access Bridge. For a non-editable text field, the state "editable" is removed from the AccessibleStateSet.

Non-editable text fields can be used on Graphical User Interfaces to display read-only information which can be changed under certain conditions. The user need to get the state information of a non-editable text field to avoid typing and confusion.

I wrote a simple application Test_JTextField_NotEditable.jar with a frame containing two JTextField objects, an editable one and a non-editable one (including labels), and attached it to this bug report: 
[Test_JTextField_NotEditable.zip](https://github.com/nvaccess/nvda/files/8680965/Test_JTextField_NotEditable.zip)
If you prefer a .java file, you can find it within the .jar file.

### Steps to reproduce:
1. Extract the Test_JTextField_NotEditable.jar file from the linked .zip file.
2. Execute the attached .jar file with an up-to-date Java Runtime Environment, e.g. JDK/JRE version 17 or 18.
-> A Java window with title "Frame with two text fields" opens.
-> The text field with the label "Editable text field" has the keyboard focus.
-> NVDA announces: "Frame with two text fields, filler, filler, Editable text field, edit, blank"
("filler" is the AccessibleRole of the Box. In my opinion, the "filler" announcement is not useful, but this is not the topic of this bug report.)
3. Press Tab key.
-> The text field with the label "Read-only text field" has the keyboard focus.
-> NVDA announces: "Filler, Read-only text field, edit, This text can not be changed".
-> NVDA does not announce that this text field is not editable.

### Actual behavior:
On non-editable text fields, NVDA announces the role "edit" without the non-editable state.

### Expected behavior:
On non-editable text fields, NVDA should additionally announce the non-editable state, e.g.: "edit, not editable".

### System configuration
#### NVDA installed/portable/running from source:
installed

#### NVDA version:
Version: 2021.3.5

#### Windows version:
Version: 10.0.19042 Build 19042

#### Name and version of other software in use when reproducing the issue:
java version "18.0.1" 2022-04-19
Java(TM) SE Runtime Environment (build 18.0.1+10-24)
Java HotSpot(TM) 64-Bit Server VM (build 18.0.1+10-24, mixed mode, sharing)

#### Other information about your system:
Java Access Bridge is enabled.

### Other questions
#### Does the issue still occur after restarting your computer?
Yes.

#### Have you tried any other versions of NVDA? If so, please report their behaviors.
Yes. Same behavior.

#### If NVDA add-ons are disabled, is your problem still occurring?
Not applicable.

#### Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?
Not applicable.


Discussion:

Resolving patch:
diff --git a/source/NVDAObjects/JAB/__init__.py b/source/NVDAObjects/JAB/__init__.py
--- a/source/NVDAObjects/JAB/__init__.py
+++ b/source/NVDAObjects/JAB/__init__.py
@@ -312,6 +312,8 @@ def _get_states(self):
 		for state in stateStrings:
 			if state in JABStatesToNVDAStates:
 				stateSet.add(JABStatesToNVDAStates[state])
+		if "editable" not in stateStrings and self._JABAccContextInfo.accessibleText:
+			stateSet.add(controlTypes.State.READONLY)
 		if "visible" not in stateStrings:
 			stateSet.add(controlTypes.State.INVISIBLE)
 		if "showing" not in stateStrings:


Test patch: