Я заранее извинюсь за отсутствие специфики в этом, но я не уверен, как это вызвано.
У нас есть XMLDocument, расширяющий javax.swing.text.DefaultStyledDocument
Если мы делаем быстрый откат/повтор вызовов (скажем, удерживая Ctrl + Z или Ctrl + Shift + Z), поток AWT EventQueue бросает Исключение:
javax.swing.text.BadLocationException: Length must be positive
getText():810, AbstractDocument {javax.swing.text}
getText():135, GlyphView {javax.swing.text}
getSpan():60, GlyphPainter1 {javax.swing.text}
getPreferredSpan():592, GlyphView {javax.swing.text}
getPreferredSpan():732, FlowView$LogicalView {javax.swing.text}
calculateMinorAxisRequirements():233, FlowView {javax.swing.text}
calculateMinorAxisRequirements():724, ParagraphView {javax.swing.text}
checkRequests():935, BoxView {javax.swing.text}
getMinimumSpan():568, BoxView {javax.swing.text}
calculateMinorAxisRequirements():903, BoxView {javax.swing.text}
checkRequests():935, BoxView {javax.swing.text}
setSpanOnAxis():343, BoxView {javax.swing.text}
layout():708, BoxView {javax.swing.text}
setSize():397, BoxView {javax.swing.text}
setSize():1714, BasicTextUI$RootView {javax.swing.plaf.basic}
modelToView():1046, BasicTextUI {javax.swing.plaf.basic}
repaintNewCaret():1311, DefaultCaret {javax.swing.text}
run():1290, DefaultCaret$1 {javax.swing.text}
dispatch():312, InvocationEvent {java.awt.event}
dispatchEventImpl():733, EventQueue {java.awt}
access$200():103, EventQueue {java.awt}
run():694, EventQueue$3 {java.awt}
run():692, EventQueue$3 {java.awt}
doPrivileged():-1, AccessController {java.security}
doIntersectionPrivilege():76, ProtectionDomain$1 {java.security}
dispatchEvent():703, EventQueue {java.awt}
pumpOneEventForFilters():242, EventDispatchThread {java.awt}
pumpEventsForFilter():161, EventDispatchThread {java.awt}
pumpEventsForHierarchy():150, EventDispatchThread {java.awt}
pumpEvents():146, EventDispatchThread {java.awt}
pumpEvents():138, EventDispatchThread {java.awt}
run():91, EventDispatchThread {java.awt}
Теперь, очевидно, это вызвано из потока обновления AWT.
Фактический элемент он бросает на это:
[4] = {[email protected]}"LeafElement(content) 223,217\n"
p0 = {[email protected]}"223"
p1 = {[email protected]}"217"
this$0 = {c[email protected]6211}
parent = {[email protected]}"BranchElement(paragraph) 191,238\n"
attributes = {[email protected]}"{family=Courier,size=12,foreground=java.awt.Color[r=0,g=0,b=0],}"
this$0 = {c[email protected]6211}
(Взято из IntelliJ отладчика).
как вы видите, p0 и p1 неверны. но этот элемент не должен быть там, так как [3] и [5] элементы в массиве соответствуют диапазону:
[3] = {[email protected]}"LeafElement(content) 215,223\n"
[4] = {[email protected]}"LeafElement(content) 223,217\n"
[5] = {[email protected]}"LeafElement(content) 223,237\n"
Я полагаю, что я хватаю синхронизацию, или SwingUtilities.runLater (...), но я понятия не имею, где, я помещал их везде, о которых я могу думать в классах Undo/Redo, которые мы используем.
Edit:
Это как редактирование добавляются в UndoManager:
public void undoableEditHappened(final UndoableEditEvent ev)
{
UndoableEdit edit = ev.getEdit();
// Include this method to ignore syntax changes
// To reduce memory consumption, do this check before adding runnable.
if (edit instanceof AbstractDocument.DefaultDocumentEvent &&
((AbstractDocument.DefaultDocumentEvent) edit).getType() ==
AbstractDocument.DefaultDocumentEvent.EventType.CHANGE)
{
return;
}
try {
UndoableEdit temp = ev.getEdit();
undoManager.addEdit(temp);
undoAction.updateState();
redoAction.updateState();
setChanged(true);
} catch (Exception e) {
e.printStackTrace();
}
}
Edit 2: Я нашел большинство вопросов, которые я видел, были вызваны функции, на invokeLater(), который пытается синтаксис выделить текст после события отмены/повтора. Я обеспокоен тем, что хотя это событие EventQueue не синхронизировано. Есть ли порядок приоритетов или что-то для порядка, в котором эти события запущены?
Никто не может помочь вам, не увидев ваш код, и я подозреваю, что слишком поздно публиковать здесь. Вам нужно будет установить контрольную точку исключения и попытаться поймать ее в действии. –
Я могу получить исключение только из потока AWT EventQueue, и именно там я получил информацию, которую я разместил выше, другого исключения не было. Я знаю, что это длинный снимок без отдельного теста, я работаю над тем, могу ли я его воссоздать (я работаю над массово старым фрагментом кода, о котором никто не знает). Что я ищу, это указатели. –
Вы можете попробовать обернуть все вызовы отмены/повтора в SwingUtilities.invokeLater(). Еще один момент - проверить, как хранятся UndoableEdits. У них есть копия структуры DOM или ссылки на структуру. Скопировать безопаснее – StanislavL