每当我在CodeArea中键入内容并按CTRL + Z,然后再次开始键入时,光标就会重置为文本的开头。
我调查了此问题https://github.com/FXMisc/RichTextFX/issues/761,似乎此错误已修复。但是,我能够复制最新版本(0.9.1)中的错误。
以下代码将复制行为:
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();
}
}
我想念什么吗?如果该bug存在,请问如何解决?
答案 0 :(得分:0)
经过简短的调试后,我发现RichTextFx在选择新范围时发生了一些奇怪的行为(从该范围开始输入文本,光标位置无关紧要)。选择新范围时,当前范围设置为0,0,然后仅移动到光标位置。但是,执行撤消操作后,新范围将选择为0,0,而不是当前光标位置。正因为如此,当我们按undo时,尽管光标在另一个位置突出显示,但文本仍从0,0开始键入。
我能够使用反射来解决这个问题。您需要扩展StyleClassedTextArea
,覆盖undo()
方法,执行撤消操作,然后设置所需范围的位置。您可以将范围设置为当前光标位置,但光标不能始终保持在正确的位置,尤其是在光标需要移动到另一段中的另一种样式时。我在undoManager的ChangeQueue中获得了正确的位置范围。
您需要确保正确投射,因此在投射之前进行一些调试。
@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
}
}
}