UndoManager hängt beim Redo

zer0

Erfahrenes Mitglied
Hallo,

ich bastel an einem Editor mit Syntaxhighlightning und Undo/Redo Operation. Ihc benutze das JTextPane und für Undo & Redo benutze ich den UndoManager von Swing. Das ganze funktioniert eigentlich auch. Nach jeder Eingabe wird der Text geparst und mittels setCharacterAttributes vom DefaulStyledDocument der Text farbig formatiert.

Das stellt auch das Problem dar, dadurch das ich setCharacterAttributes aufrufe wird auch dieses UndoEvent, also die Formatänderung, in der Undo Historie abgelegt. Dazu habe ich mir eine kleine abhilfe gemacht die auch funktioniert ABER wenn das JTextPane ganz leer ist, also z.B. alle Undo's gemacht wurden UND dann wird ein Redo gemacht hängt sich das Programm auf. Nach ca. 2min's geht es wieder.

Meine Abhilfe ist das einafch vor dem Formatieren des Textes wird eine Variable im UndoManager auf false gesetzt, und ab da an werden keine UndoEvent's mehr gespeichert.

Hier mal ein Ausschnit aus meiner ContentPanel Datei, in der auch das JTextPane etc. ist.

Java:
public ContentPanel() {
		initialize();
		initializeComponents();
		textPane.getDocument().addUndoableEditListener(undoableEditListener = new MyUndoableEditListener());
	}

public void redo() {
		try {
            undo.redo();
        } catch (CannotRedoException ex) {
            System.out.println("Unable to redo: " + ex);
            ex.printStackTrace();
        }
        updateRedoState();
        updateUndoState();
	}
	
	public void undo() {
		try {
            undo.undo();
        } catch (CannotUndoException ex) {
            System.out.println("Unable to undo: " + ex);
            ex.printStackTrace();
        }
        updateUndoState();
        updateRedoState();
	}
	
	public void highlightDocument() {
		undoableEditListener.setHighlightMode(true);
		
				// Code...
				// ...
		
        		attr = highlighter.getAttributeSet(word);
        		// Hier passiert die Formatänderung
            	document.setCharacterAttributes(offset, length, attr, true);
            	
            	
            }
        } catch (BadLocationException ble) {
            System.err.println("Couldn't insert initial text.");
        }
        
        undoableEditListener.setHighlightMode(false);
    }
	
	public void updateUndoState() {
        if(undo.canUndo()) {
        	UndoAction.getInstance().setEnabled(true);
            //System.out.println(undo.getUndoPresentationName());
        } else {
        	UndoAction.getInstance().setEnabled(false);
        }
    }
	
	public void updateRedoState() {
        if (undo.canRedo()) {
        	RedoAction.getInstance().setEnabled(true);
            //System.out.println(undo.getRedoPresentationName());
        } else {
        	RedoAction.getInstance().setEnabled(false);
        }
    }
    
	class MyUndoableEditListener implements UndoableEditListener {
    	
		private boolean highlightMode = false;
		
        public boolean isHighlightMode() {
			return highlightMode;
		}

		public void setHighlightMode(boolean highlightMode) {
			this.highlightMode = highlightMode;
		}

		public void undoableEditHappened(UndoableEditEvent e) {
			// Hier wenn der HighlightMode aus ist (=false) dann werden die UndoEvent's gespeichert
                        if(isHighlightMode() == false) {
				undo.addEdit(e.getEdit());
            	                updateUndoState();
            	                updateRedoState();
			}
        }
    }

Und hier noch eine Action, die ausgeführt wird wenn STRG-Z gedrückt wird:
Java:
private UndoAction(String name, Icon icon) {
		super(name, icon);
		putValue(Action.SHORT_DESCRIPTION, name);
		setEnabled(false);
	}
	
	@Override
	public void actionPerformed(ActionEvent arg0) {
		System.out.println(getValue(NAME));
		MainFrame.getContentPanel().undo();
	}

Ich hoffe mir kann jemand bei diesem Problem helfen! :$
 
Zuletzt bearbeitet:
Zurück