1

Whenever, I type something in CodeArea and press CTRL + Z and then begin typing again, the cursor gets reset to the start of the text.

I looked into this issue https://github.com/FXMisc/RichTextFX/issues/761 and seems like this bug is fixed. However, I was able to replicate the bug in latest version (0.9.1).

Following code will replicate the behavior:

public class GuiTest extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        StyleClassedTextArea  codeArea = new StyleClassedTextArea();
        codeArea.replaceText("Text");

        VirtualizedScrollPane<StyleClassedTextArea> scrollPane = new VirtualizedScrollPane<>(codeArea);

        final Scene scene = new Scene(scrollPane, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

Am I missing something? If the bug exists any idea how to solve it?

Enigo
  • 3,685
  • 5
  • 29
  • 54
THe_strOX
  • 687
  • 1
  • 5
  • 16
  • yes, it definitely doesn't work on my machine as well with either `SNAPSHOT` or latest release version. and since the official support for that project is down now I'm not sure that it will be fixed anytime soon – Enigo Jul 23 '18 at 20:56
  • This bug was fixed in version 0.9.2 – Jurgen Apr 22 '19 at 13:51

1 Answers1

0

After a brief debugging I found that RichTextFx is doing some weird behavior when selecting the new range (it is from this range you start typing the text, cursor position does not matter). When selecting the new range, the current range is set to 0,0 and then only moved to the cursor position. However, after performing the undo, the new range is selected to 0,0 and never to the current cursor position. It is because of that when we press undo, though the cursor is highlighted in another position, the text starts getting typed from the 0,0.

I was able to somewhat solve this using reflection. You need to extend the StyleClassedTextArea, override the undo() method, perform undo, and then set the position where you need your range in. You could set the range to the current cursor position but the cursor is not always in the correct position especially when the cursor needs to move to another style in another paragraph. I got the correct position range inside the ChangeQueue in the undoManager.

You need to make sure that you are casting properly so, do some debugging before casting.

@Override
public void undo() {
    if (isUndoAvailable()) {
        super.undo();
        UndoManager undoManager = getUndoManager();
        try {
            Field queueField = UndoManagerImpl.class.getDeclaredField("queue");
            queueField.setAccessible(true);
            UnlimitedChangeQueue queue = (UnlimitedChangeQueue) queueField
                    .get(undoManager);
            int newRange = ((PlainTextChange) ((List) queue.peekNext()).get(0))
                    .getRemovalEnd();
            selectRange(newRange, newRange);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            // Handle exception
        }
    }
}

@Override
public void redo() {
    if (isRedoAvailable()) {
        super.redo();
        UndoManager undoManager = getUndoManager();
        try {
            Field queueField = UndoManagerImpl.class.getDeclaredField("queue");
            queueField.setAccessible(true);
            UnlimitedChangeQueue queue = (UnlimitedChangeQueue) queueField
                    .get(undoManager);
            int newRange = ((PlainTextChange) ((List) queue.peekPrev()).get(0))
                    .getInsertionEnd();
            selectRange(newRange, newRange);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            // Handle
        }
    }
}
THe_strOX
  • 687
  • 1
  • 5
  • 16