RFR: 8176270: Adding ChangeListener to TextField.selectedTextProperty causes StringOutOfBoundsException
Kevin Rushforth
kcr at openjdk.java.net
Fri Feb 7 18:26:54 UTC 2020
On Sat, 21 Dec 2019 15:36:14 GMT, Oliver Kopp <github.com+1366654+koppor at openjdk.org> wrote:
> This is a WIP PR. Requesting for comments.
>
> I could not replicate the test given at https://bugs.openjdk.java.net/browse/JDK-8176270 without TestFX. I nevertheless let my try to replicate the @Test things in here.
>
> The fix is just a wild guess without really understanding the side effects of `.addListener`.
I left comments inline. This will need changes. Also, you will need to provide a test that fails without the fix and passes with the fix.
modules/javafx.controls/src/main/java/javafx/scene/control/TextInputControl.java line 168:
> 167: // Ensure that the last character to get is within the bounds of the txt string
> 168: if (end >= start + length) end = length-1;
> 169: // In case the start is after the whole txt, nothing valid is selected. Thus, return the default.
First, I think the existing test is simply wrong: Why should the `start` value matter when checking whether the `end` value needs to be clamped -- it's an `end` point not a number of characters. I think the entire problem might be the fact that it is comparing against `start + length`. Second, the value to be clamped to was correct before your change. The `substring` method to which `end` is passed is documented as subtracting 1.
I think the test should be something like:
if (end > length) end = length;
modules/javafx.controls/src/main/java/javafx/scene/control/TextInputControl.java line 170:
> 169: // In case the start is after the whole txt, nothing valid is selected. Thus, return the default.
> 170: if (start >= length) return "";
> 171: return txt.substring(start, end);
This change seems OK, and might be clearer and the existing code, but the existing code is correct, and produces the same effect.
modules/javafx.controls/src/test/java/test/javafx/scene/control/TextInputControlTest.java line 2088:
> 2087: Semaphore semaphore = new Semaphore(0);
> 2088: Platform.runLater(semaphore::release);
> 2089: semaphore.acquire();
Since controls tests run using the StubToolkit, `Platform.runLater` does not do what you expect. If you need to run a pulse to get some code to run that normally would run as part of pulse, you can call that method directly. See other controls tests for how this is done.
-------------
Changes requested by kcr (Lead).
PR: https://git.openjdk.java.net/jfx/pull/73
More information about the openjfx-dev
mailing list