Repository: nvaccess/nvda

Issue:
nvda does not read the window name correctly in a java application

### Steps to reproduce:
Open a java application with multiple windows, each window must have a different name.
### Actual behavior:
Press nvda + t to have nvda read the name of the current window.
Nvda announces the name of the first window of the java application.
### Expected behavior:
Nvda should read the name of the current java application window, and should not repeat the name of the first open java window in the application.
### System configuration
#### NVDA installed/portable/running from source:
install
#### NVDA version:
alfa 16587 e 2018.4.1
#### Windows version:
10 16299
#### Name and version of other software in use when reproducing the issue:
The java application used is an application written within the company I work for.
#### Other information about your system:

### Other questions
#### Does the issue still occur after restarting your PC?
yes
#### Have you tried any other versions of NVDA?
yes
I tested with a version recommended by the organization where I work 2016.3 and it works correctly.
Java SwingSet2 application with NVDA
I have encountered some issues with the SwingSet2 application, which is a Java Swing application that Oracle suggest is suitable for testing whether the Java Access Bridge is working correctly.

I have listed several issues. Some items might be due to my ignorance. Some items might be due to my high expectations. Some items might be due to inevitable behavior when using the Java Access Bridge or Java Swing applications. Some items might be due to the way the Java Swing application is written. Some items might be NVDA bugs or feature requests. I asked for help with this on the NVDA mailing list, but I did not receive a reply. I am sorry if my report is unconventional.

### Steps to reproduce:

These instructions apply to 64-bit Microsoft Windows.

1. Install the Java Runtime Environment available from the page at the following address:
https://www.java.com/en/download/manual.jsp
2. Enable the Java Access Bridge, using the instructions on the page at the following address:
https://docs.oracle.com/javase/8/docs/technotes/guides/access/enable_and_test.html
The 32-bit Java Access Bridge DLL (WindowsAccessBridge-32.dll) should be in the sysWOW64 folder (usually C:\Windows\sysWOW64\). The 64-bit Java Access Bridge DLL (WindowsAccessBridge-64.dll) should be in the system32 folder (usually C:\Windows\system32\).
3. Download jdk-8u211-windows-x64-demos.zip from the page at the following address:
https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
4. Extract the files from the .zip archive.
5. Start demo\jfc\SwingSet2\SwingSet2.jar with a command of the form <code>java -jar SwingSet2.jar</code>.
6. Press the Tab key to navigate to the "JButton, JRadioButton, JToggleButton, JCheckbox demos" toggle button. NVDA says "toggle button 0 not pressed JButton, JRadioButton, JToggleButton, JCheckbox demos 2 of 16". Why does NVDA say "0"? Doing so does not seem useful here.
7. Press the Space key to activate the toggle button. NVDA says "1 checked". Why does NVDA say "1"? Doing so does not seem useful here. Saying "pressed" might be more helpful than "1 checked". (This is likely to be related to item 6.)
8. NVDA now reads the toggle button as "toggle button 1 not pressed checked JButton, JRadioButton, JToggleButton, JCheckbox demos 2 of 16". Why does NVDA say "1 not pressed" when "pressed" would probably be more helpful? (This might be related to items 6 and 7.)
9. Press the Tab key until you reach the "Three!" button. Press NVDA+Up Arrow quickly to get NVDA to spell the label of the button. NVDA spells three spaces before the button label. Is this what you would expect?
10. In the "Image Buttons" group, should NVDA read the image buttons as "button"? (Perhaps the images have no alternative text labels.)
11. In the "Display Options" group of check boxes and the "Pad Amount" group of radio buttons, should NVDA read the "Display Options" or "Pad Amount" group label? I expected to hear the group label as I use Tab or Shift+Tab to enter the group, but I do not hear it. Perhaps the group label is not correctly associated with the check boxes or the radio buttons.
12. Press the "JColorChooser demo" toggle button. NVDA stops responding. After restarting NVDA, NVDA has no access to the Java Swing application. Is there anything that the user or the developer of the application can do to re-establish access? The only method that I have found is exiting the Java Swing application and starting it again. Is there anything that NVDA can do to establish access with a Java application that is already running?
13. Press the "JOptionPane Demo" toggle button.
14. Press the "Show Input Dialog" button. A dialog box appears. NVDA does not read the label of the edit field. When I press NVDA+B, NVDA does not properly read the dialog box. After pressing Alt+Tab twice to switch to another application and back again, I can use NVDA+B to learn that I am being asked "What is your favorite movie?". Should NVDA read the label or is it not correctly associated with the edit field?
15. Enter some text in the edit field and press the "OK" button. A message box appears. When it does so, NVDA reads the message, but NVDA+B does not get NVDA to read the message to me again. Should it? If I use Alt+Tab twice to switch to another application and back again, NVDA+B reads the message box to me, as expected.
16. Press the "JTabbedPane demo" toggle button.
17. The tab control has four tabs with the labels "Hania", "Ewan", "Laine", and "Bouncing Babies!". Should NVDA report the number of the tab and the number of tabs (for example, "tab 1 of 4")? This would be useful, because the tab panel control wraps.
18. Select the "Bouncing Babies!" tab and press NVDA+Up Arrow twice quickly to get NVDA to spell the label of the tab. NVDA spells four spaces at the start of the label. Is this what you would expect? (This might be related to item 9.)
19. Press the "JTable demo" button. In the "Favorite Food" column of the table, NVDA does not read the contents of the column. (Perhaps the images have no alternative text labels.) (This might be related to item 10.)

### System configuration
#### NVDA installed/portable/running from source:
Installed
#### NVDA version:
2019.1.1
#### Windows version:
10.0.17763 Build 17763

### Other questions
#### Does the issue still occur after restarting your PC?
Yes
#### Have you tried any other versions of NVDA? If so, please report their behaviors.
Same behavior with NVDA 2018.3 (with earlier versions of the Java runtime environment).
[nvda-old2.log](https://github.com/nvaccess/nvda/files/3282903/nvda-old2.log)
[nvda-old.log](https://github.com/nvaccess/nvda/files/3282904/nvda-old.log)
[nvda.log](https://github.com/nvaccess/nvda/files/3282905/nvda.log)





Discussion:
@fernando-jose-silva: Which Java SE Runtime Environment version is installed?
the java installed are the 64-bit and 32-bit versions (the 32-bit version was installed per end) version 8 update 201
Duplicate of #7571


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
@@ -97,13 +97,21 @@
 }
 
 
+re_simpleXmlTag = re.compile(r"(\<[^>]+\>)+")
 
-re_simpleXmlTag=re.compile(r"\<[^>]+\>")
 
+def _subHtmlTag(match: re.match) -> str:
+	""" Determines whether to replace the tag with a space or to just remove it. """
+	startIndex, endIndex = match.span()
+	return "" if (
+		startIndex == 0 or match.string[startIndex - 1].isspace()
+		or endIndex == len(match.string) or match.string[endIndex].isspace()
+	) else " "
 
-def _processHtml(text):
+
+def _processHtml(text: str) -> str:
 	""" Strips HTML tags from text if it is HTML """
-	return re_simpleXmlTag.sub(" ", text) if text.startswith("<html>") else text
+	return re_simpleXmlTag.sub(_subHtmlTag, text) if text.startswith("<html>") else text
 
 
 class JABTextInfo(textInfos.offsets.OffsetsTextInfo):
@@ -320,6 +328,9 @@ def _get_states(self):
 		for state in stateStrings:
 			if state in JABStatesToNVDAStates:
 				stateSet.add(JABStatesToNVDAStates[state])
+		if self.role is controlTypes.Role.TOGGLEBUTTON and controlTypes.State.CHECKED in stateSet:
+			stateSet.discard(controlTypes.State.CHECKED)
+			stateSet.add(controlTypes.State.PRESSED)
 		if "editable" not in stateStrings and self._JABAccContextInfo.accessibleText:
 			stateSet.add(controlTypes.State.READONLY)
 		if "visible" not in stateStrings:
@@ -333,7 +344,15 @@ def _get_states(self):
 		return stateSet
 
 	def _get_value(self):
-		if self.role not in [controlTypes.Role.CHECKBOX,controlTypes.Role.MENU,controlTypes.Role.MENUITEM,controlTypes.Role.RADIOBUTTON,controlTypes.Role.BUTTON] and self._JABAccContextInfo.accessibleValue and not self._JABAccContextInfo.accessibleText:
+		if (
+			self.role not in [
+				controlTypes.Role.TOGGLEBUTTON, controlTypes.Role.CHECKBOX,
+				controlTypes.Role.MENU, controlTypes.Role.MENUITEM,
+				controlTypes.Role.RADIOBUTTON, controlTypes.Role.BUTTON
+			]
+			and self._JABAccContextInfo.accessibleValue
+			and not self._JABAccContextInfo.accessibleText
+		):
 			return self.jabContext.getCurrentAccessibleValueFromContext()
 
 	def _get_description(self):
@@ -372,7 +391,14 @@ def _get_positionInfo(self):
 				return info
 
 		parent=self.parent
-		if isinstance(parent,JAB) and self.role in (controlTypes.Role.TREEVIEWITEM,controlTypes.Role.LISTITEM):
+		if (
+			isinstance(parent, JAB)
+			and self.role in (
+				controlTypes.Role.TREEVIEWITEM,
+				controlTypes.Role.LISTITEM,
+				controlTypes.Role.TAB
+			)
+		):
 			index=self._JABAccContextInfo.indexInParent+1
 			childCount=parent._JABAccContextInfo.childrenCount
 			info['indexInGroup']=index
@@ -389,7 +415,7 @@ def _get_activeChild(self):
 	def _get_parent(self):
 		if not hasattr(self,'_parent'):
 			jabContext=self.jabContext.getAccessibleParentFromContext()
-			if jabContext:
+			if jabContext and self.indexInParent is not None:
 				self._parent=JAB(jabContext=jabContext)
 			else:
 				self._parent=super(JAB,self).parent


Test patch:
diff --git a/tests/unit/test_javaAccessBridge.py b/tests/unit/test_javaAccessBridge.py
--- a/tests/unit/test_javaAccessBridge.py
+++ b/tests/unit/test_javaAccessBridge.py
@@ -25,8 +25,8 @@ def test_regexNotModified(self):
 		self.assertEqual(regexStr, JAB._processHtml(regexStr))
 
 	def test_htmlStringHasTagsRemoved(self):
-		htmlStr = "<html><body><p>Some <b>bold</b> text.</p></body></html>"
-		expected = "   Some  bold  text.   "
+		htmlStr = "<html><body><p>Some <b>bold</b> <i>text</i>.</p></body></html>"
+		expected = "Some bold text ."
 		self.assertEqual(expected, JAB._processHtml(htmlStr))