# Undo/Redo funktioniert nicht richtig



## Guest (26. Nov 2007)

Hallo,

habe folgendes Problem. Wenn ich in meinem Zeichentool die Objekte verschiebe, wird gleich der aktuelle Stand(Position) aller Objekte in einem Vector abgespeichert.


```
public static Vector<PolyHistory> polyHistoryState = new Vector<PolyHistory>();


void fuegeActioninHistoryEin(Vector<MeinPolygon> vector) {
	   polyHistoryState.addElement(new PolyHistory(vector));
	   HauptFenster.activateUndoButton = true;
	   HauptFenster.undoButton.setIcon(new ImageIcon("IconPic/zurueckA.gif"));
}

fuegeActioninHistoryEin((Vector<MeinPolygon>) polyXML.getMarks().clone());
```

Sobald eine Änderung der Objekte stattfindet, wird es sofort in die XML-Datei geschrieben. Bei Bedarf werden die Objekte auch aus der XML-Datei gelesen.


Meine Undo-Methode :


```
int buttonClicks = 0;
int currentIndex = 0;

if (activateUndoButton) {			
   int i = PolygonMarkierung.polyHistoryState.size()-1;
   buttonClicks++;
   PolyHistory pH;
						
   if ((i - buttonClicks) >= 0) {
     pH = PolygonMarkierung.polyHistoryState.elementAt(i-buttonClicks);
     zF.setShowRec(false);
     zF.setShowNodes(false);
							
     ZeichenFlaeche.showedPolyElements.clear();						     ZeichenFlaeche.orgPolyElements.clear();
							
     ZeichenFlaeche.showedPolyElements.addAll(pH.getVector());
     ZeichenFlaeche.orgPolyElements.addAll(pH.getVector());
						}
     currentIndex = (i-buttonClicks);		
							
     if (currentIndex < i) {
	activateRedoButton = true;
	redoButton.setIcon(new ImageIcon("IconPic/vorA.gif"));
     }
   }
   if (i - buttonClicks == 0) {
     activateUndoButton = false;
     undoButton.setIcon(new ImageIcon("IconPic/zurueckP.gif"));
   } 							
}

if (activateRedoButton) {								
  int i = PolygonMarkierung.polyHistoryState.size()-1;
  // hat hier keine an andere Funktion
  buttonClicks--;
  PolyHistory pH;
						
  if (currentIndex < i) {
    currentIndex++;
    pH = PolygonMarkierung.polyHistoryState.elementAt(currentIndex);
											
    zF.setShowRec(false);
    zF.setShowNodes(false);
							
    ZeichenFlaeche.showedPolyElements.clear();
    ZeichenFlaeche.orgPolyElements.clear();
							
    ZeichenFlaeche.showedPolyElements.addAll(pH.getVector());	
    ZeichenFlaeche.orgPolyElements.addAll(pH.getVector());

    pH = null;
							
    if (currentIndex > 0) {
      activateUndoButton = true;
      undoButton.setIcon(new ImageIcon("IconPic/zurueckA.gif"));
    }						
  }
  if (currentIndex == i) {
    activateRedoButton = false;
    redoButton.setIcon(new ImageIcon("IconPic/vorP.gif"));
  }
}
```

Das Problem ist, dass das undo/redo erst dann richtig funktioniert, wenn ich zuvor die objekte ändere und gleich danach undo/redo benutze, aber bei nachträglichen Änderungen kommt undo/redo nicht mehr ganz klar. 

Das komische ist, wenn ich ganz am Anfang 10 objekte ändere und dann undo/redo willkürlich aufrufe, funktioniert es einwandfrei. Die Undo/Redo Methoden haben auch keinen Einfluss auf den Vector, wodrin die Vectoränderungen abgespeichert werden. Sie werden ja nur aufgerufen und angezeigt. 

Wenn ich zB. ein einziges Objekt verschiebe, dann erst undo und dann redo aufrufe, und gleich danach eine andere Änderung vornehme, wird bei der ersten undo  keine Änderung angezeigt, beim zweiten undo dafür dann beide. Bei Redo bei der ersten Betätigung werden beide Änderung angezeigt und beim zweiten dafür keine. 

Was kann die Ursache sein ?


----------



## Guest (27. Nov 2007)

Hat niemand eine Ahnung. Vielleicht ist die Frage etwas schlecht beschrieben wurden.

Wenn ich vor der Undo/Redo Betätigung beliebig viele Objekte ändere und anschließend beliebig oft undo/redo Aufrufe funktioniert alles wie gewünscht. Wenn ich mittel Redo die Zeichenfläche wieder  auf den aktuellsten Stand bringe, und anschließend eine Änderung vornehme, wird dann beim ersten Undo die letzte Änderung nicht rückgängig gemacht,  beim zweiten Undo werden dafür die letzten beiden Änderung aus einmal angezeigt. Bei Redo ist es genau der umgekerte Vorgang. Beim vorletzten Redo werden wir letzten beiden Änderungen angezeigt, und beim letzten Redo dann natürlich nichts, weil es ja beim vorletzten Redo schon auf den aktuellsten Stand war.

Es scheint, dass der letzte Vectoreintrag einfach leer zu sein scheint. 

Mittels Undo/Redo rufe aber nur die Objekte aus dem Vector auf. Wie kann es sein, dass es die ersten Änderung vor Undo/Redo richtig der Reihe nach angezeigt werden, aber nach der Betätigung der Tasten aber die Vector einträge nicht mehr stimmen ?


----------



## SlaterB (27. Nov 2007)

die Frage ist schön ausführlich gestellt, das Problem an sich aber in keiner Weise nachvollziehbar,
niemand weiß, was in deiner GUI so passiert, oder gar in deiner XML-Datei,
der Einfluss des Vectors ist höchstens zu erahnen

dein Code scheint nicht viel davon wiederzugeben, ist auch hoffnungslos, da sicher soviel

auf dem Level kann man eigentlich nur mit lokalem Testen des ganzen Codes arbeiten,
-------
allgemeine Tipps:
mach aus deinem Programm ein Log-Programm,
jedes Speichern/ Lesen aus der Liste, jedes Speichern/ Lesen aus der Datei, 
jede User-Aktion wie Mausklick + jede interne Aktion wie Undo/ Redo,
jede Zeichnung in der GUI sollte mit einem Text in der Konsole erklärt werden,
dann weiß man, was das Programm wann wieso macht

Log:
- User klickt auf Redo
- Redo-Liste ist leer, keine Aktion
- User malt x
- User klinkt auf Undo
- füge folgende Zeichenoperation in Redo-Liste ein: y
....
- speichere XML-Datei, kompletter Inhalt: z
....

usw.


----------

