diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java b/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java index 811632ee7..760884f6f 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java @@ -1300,6 +1300,9 @@ public void replaceText(int start, int end, String text) { @Override public void replace(int start, int end, StyledDocument replacement) { content.replace(start, end, replacement); + + int newCaretPos = start + replacement.length(); + selectRange(newCaretPos, newCaretPos); } @Override diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/model/GenericEditableStyledDocumentBase.java b/richtextfx/src/main/java/org/fxmisc/richtext/model/GenericEditableStyledDocumentBase.java index 7763ea2eb..921b38f64 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/model/GenericEditableStyledDocumentBase.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/model/GenericEditableStyledDocumentBase.java @@ -122,6 +122,10 @@ public Position offsetToPosition(int offset, Bias bias) { @Override public void replace(int start, int end, StyledDocument replacement) { ensureValidRange(start, end); + if (replacement.length() == 0 && start == end) { + // ignore a replacement that doesn't do anything + return; + } doc.replace(start, end, ReadOnlyStyledDocument.from(replacement)).exec(this::update); } diff --git a/richtextfx/src/test/java/org/fxmisc/richtext/model/StyledTextAreaBehaviorTest.java b/richtextfx/src/test/java/org/fxmisc/richtext/model/StyledTextAreaBehaviorTest.java index c98a45716..e6e7b11f0 100644 --- a/richtextfx/src/test/java/org/fxmisc/richtext/model/StyledTextAreaBehaviorTest.java +++ b/richtextfx/src/test/java/org/fxmisc/richtext/model/StyledTextAreaBehaviorTest.java @@ -84,6 +84,7 @@ public void setup() { interact(() -> { area.setDisable(true); area.replaceText("When Area Is Disabled Test: Some text goes here"); + area.moveTo(0); }); } @@ -136,6 +137,8 @@ public void draggingTheMouseDoesNotSelectText() { @Test public void releasingTheMouseAfterDragDoesNothing() { + assertEquals(0, area.getCaretPosition()); + moveTo(firstLineOfArea()) .press(MouseButton.PRIMARY) .dropBy(20, 0); @@ -155,7 +158,10 @@ public class AndTextIsNotSelected extends InlineCssTextAreaAppTest { @Before public void setup() { - interact(() -> area.replaceText(firstParagraph)); + interact(() -> { + area.replaceText(firstParagraph); + area.moveTo(0); + }); } @Test @@ -357,4 +363,23 @@ public void pressingMouseOnSelectionAndDraggingAndReleasingMovesSelectedTextToTh } + public class KeyboardBehaviorTests extends InlineCssTextAreaAppTest { + + @Test + public void typingALetterMovesTheCaretAfterThatInsertedLetter() { + interact(() -> { + area.moveTo(0); + area.clear(); + }); + + String userInputtedText = "some user-inputted text"; + clickOn(area).write(userInputtedText); + + assertEquals(userInputtedText, area.getText()); + assertEquals(userInputtedText.length(), area.getCaretPosition()); + assertTrue(area.getSelectedText().isEmpty()); + } + + } + } \ No newline at end of file