On Wed, 27 May 2020 10:09:52 GMT, Jeanette Winzenburg <faste...@openjdk.org> 
wrote:

>> Clearing the selection temporarily works fine to prevent the 
>> StringOutOfBoundsException but will also change
>> selectionProperty to reflect the selection being 0/0 for a short time.
>
> you are hacking around ;)
> 
> doSelect _must not_ be called somewhere "in-between" changing the text: the 
> api doc clearly states that the
> caret/anchor coordinates are the _new_ coordinates, that is after all changes 
> have been applied. When re-calculating
> them on-the-fly might have unexpected side-effects, f.i. if a TextFormatter 
> had something special in mind (no failing
> test handy though).

Most of the time, value in 
javafx.scene.control.TextInputControl.replaceText(int, int, String, int, int) 
will already
be filtered (e.g. linebreaks in TextField) In that case, adjustmentAmount will 
be zero and one could just do the
selection before actually inserting the text.

But a case can be constructed with a TextFormatter that will produce characters 
that will be filtered by the TextField
itself:
    
    @Test public void replaceSelectionWithFilteredCharacters() {
        txtField.setText("x xxxyyy");
        txtField.selectRange(2, 5);
        txtField.setTextFormatter(new TextFormatter<>(this::noDigits));
        txtField.replaceSelection("a1234a");
        assertEquals("x aayyy", txtField.getText());
        assertEquals(4, txtField.getSelection().getStart());
        assertEquals(4, txtField.getSelection().getStart());
    }

    private Change noDigits(Change change) {
        Change filtered = change.clone();
        filtered.setText(change.getText().replaceAll("[0-9]","\n"));
        return filtered;
    }

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

PR: https://git.openjdk.java.net/jfx/pull/138

Reply via email to