Frage

Ein Teil meines Projektes ist es, einen Texteditor zu schreiben, die für das Schreiben einige Regeln verwendet wird, meine Anwendung kompiliert und ausgeführt wird. Schreiben Compiler war Ende und Release Beta-Version. In der endgültigen Fassung fügen wir müssen Undo und Redo, um den Texteditor. Ich benutze eine Datei und speichern Sie sie in regelmäßigen Abständen für den Texteditor. Wie Undo und Redo zu meinem Text-Editor zu entwerfen? Was in der Struktur der persistenten der Datei geändert wird?

War es hilfreich?

Lösung

Sie können Ihre Aktionen wie Befehle modellieren, dass Sie in zwei Stapeln halten. Eine für Undo, eine andere für Redo. Sie können compose Ihre Befehle mehr High-Level-Befehle zu erstellen, wie wenn man das rückgängig machen wollen Aktionen eines Makros, zum Beispiel; oder wenn Sie einzelne Tastenanschläge eines einzelnen Wortes gruppieren möchten, oder eine Phrase in einer gemeinsamen Aktion.

Jede Aktion in Ihrem Editor (oder eine Redo-Aktion) erzeugt einen neuen Undo-Befehl, der in den Rückgängig-Stapel geht (und löscht auch den Redo-Stack). Jede undo Aktion erzeugt den entsprechenden Redo-Befehl, der die Wiederherstellungsstapel übergeht.

Sie können auch wie bereits erwähnt, in den Kommentaren von derekerdmann , kombinieren beide Undo und Redo-Befehle in eine Art von Befehl , die wissen, wie seine Aktion rückgängig zu machen und zu wiederholen.

Andere Tipps

Es gibt grundsätzlich zwei gute Möglichkeiten, um darüber zu gehen:

  • "Befehl" Entwurfsmuster

  • mit nur OO über unveränderliche Objekte, wo alles nur unveränderliche Objekte aus unveränderlichen Objekten selbst von unveränderlichen Objekten (dies weniger verbreitet ist, aber wunderbar elegant, wenn es richtig gemacht)

Der Vorteil von OO über unveränderliche Objekte über den naiven Befehl oder die naive Undo / Redo ist, dass Sie brauchen nicht viel darüber nachzudenken: Sie brauchen keine „Rückgängig“ die Wirkung einer Handlung und keine Notwendigkeit zu " Replay“alle Befehle. Alles, was Sie ist ein Zeiger auf eine riesige Liste von unveränderlichen Objekten benötigt.

Da Objekte sind unveränderlich alle „Zustände“ kann unglaublich leicht sein, weil Sie können cache / Wiederverwendung meisten Objekte in jedem Zustand.

„OO über unveränderliche Objekte“ ist ein reines Juwel. Wahrscheinlich nicht gonna Mainstream bevor weitere 10 Jahre geworden, sagte; )

P. S: tun OO über unveränderliche Objekte vereinfacht auch erstaunlich parallele Programmierung.

Wenn Sie etwas Phantasie nicht wollen, können Sie einfach fügen Sie ein UndoManager . Ihre Document wird ausgelöst, wenn eine UndoableEdit jedes Mal, wenn Sie Text hinzufügen oder entfernen. Rückgängig zu machen und jede Änderung zu wiederholen, einfach diese Methoden in UndoManager nennen.

Die Kehrseite der Medaille ist UndoManager fügt eine neue bearbeiten jedes Mal der Benutzer etwas in, so die Eingabe von „apple“ werden Sie mit 5 Bearbeitungen rückgängig gemacht werden einer nach dem anderen verlassen. Für meinen Text-Editor, schrieb ich einen Wrapper für Bearbeitungen, dass speichert die Zeit, es wurde zusätzlich zu Textänderung und Offset sowie ein UndoableEditListener gemacht, dass verkettet neue Änderungen an früheren, wenn es nur eine kurze Zeit zwischen ihnen ( 0,5 Sekunden funktioniert gut für mich).

Das funktioniert gut für die allgemeine editting, aber verursacht Probleme, wenn eine massive ersetzen erfolgt. Wenn Sie ein Dokument mit 5000 Fällen von „apple“ hatten und man wollte dies mit „orange“ ersetzen, würden Sie mit 5000 Änderungen aller Speicherung „apple“, „orange“ und ein Offset-Ende. Um die Menge des verwendeten Speichers zu senken, habe ich das als ein separaten Fall zu gewöhnlichen Änderungen behandelt und bin stattdessen Speicher „Apfel“, „orange“ und eine Reihe von 5000-Offsets. Ich habe das nicht auf die Anwendung noch dazu gekommen, aber ich weiß, dass es dann einige Kopfschmerzen verursachen, wenn mehrere Strings die Suchbedingung übereinstimmen (zB. Groß- und Kleinschreibung Suche, regex Suche).

Wow, was für ein conicidence - Ich habe buchstäblich in der letzten Stunde umgesetzt Undo / Redo in meinem WYSIWYG-Texteditor:

Die Grundidee ist es, entweder speichert den gesamten Inhalt des Texteditors in einem Array oder die Differenz zwischen dem zuletzt.

Update dieses Array an wichtigen Punkten, das heißt all paar Zeichen (überprüfen Sie die Länge des Inhalts jeden Tastendruck, wenn sie mehr als etwa 20 Zeichen anders als einen Spar Punkt machen). Auch bei Änderungen in Styling (wenn Rich Text), das Hinzufügen von Bildern (falls dies erlaubt), Einfügen von Text, etc. Sie müssen auch einen Zeiger (nur ein int-Variable) zu Punkt, an dem Elemente im Array ist der aktuelle Stand der editor)

Machen Sie das Array eine bestimmte Länge haben. Jedes Mal, wenn Sie eine speichern Punkt hinzufügen möchten, fügen Sie es zu Beginn des Arrays, und alle anderen Datenpunkte nach unten durch ein bewegen. (Das letzte Element im Array vergessen werden, sobald Sie so viele speichern Punkte)

Wenn der Benutzer die Undo-Taste drückt, um zu sehen, ob der aktuelle Inhalt des Editors das gleiche wie die neuesten speichern ist (wenn sie nicht sind, dann hat der Benutzer speichert Punkt seit dem letzten Änderungen vorgenommen, so speichern Sie die aktuellen Inhalt des Editors (so kann es Redo-ed sein), machen den Editor gleich speichern Punkt auf dem letzten, und die Zeigervariable = 1 (2 Artikel in Array) machen. Wenn sie sie gleich sind, dann haben keine Änderungen vorgenommen worden seit dem letzten Speicherpunkt, so dass Sie vor, dass bis zu dem Punkt rückgängig machen müssen. um dies zu tun, erhöhen Sie den Zeigerwert + 1, und den Inhalt des Editors machen = der Wert des Zeigers.

Um Redo einfach den Zeigerwert um 1 zu verringern und den Inhalt des Arrays geladen werden (stellen Sie sicher, zu überprüfen, ob Sie das Ende des Feldes erreicht haben).

Wenn die Benutzer Änderungen nach Verhängnis machen, dann die spitze Wert Array-Zelle bewegen bis zu Zelle 0, und bewegen Sie die um den gleichen Betrag ausruhen (Sie brauchen nicht auf andere Sachen wiederholen wollen, sobald sie verschiedene Änderungen vorgenommen haben).

Ein anderer wichtiger Fang Punkt - stellen Sie sicher, dass Sie nur eine speichern Punkt hinzufügen, wenn der Inhalt des Texteditors tatsächlich geändert haben (sonst Sie erhalten doppelte Punkte sparen und es wird scheinen, wie Undo nichts an den Benutzer zu tun ist.

Ich kann Ihnen nicht mit Java-Spezifika helfen, aber ich bin glücklich, weitere Fragen zu beantworten, die Sie haben,

Nico

Sie können es auf zwei Arten tun:

  • hält eine Liste der Editor Staaten und einen Zeiger in der Liste; Rückgängig bewegt die Zeiger zurück und stellt den Zustand dort, Redo vorwärts bewegt stattdessen wirft etwas zu tun, alles über den Zeiger und fügt den Zustand als das neue Top-Element weg;
  • halten nicht Staaten, sondern Aktionen, die für jede Aktion erfordert, dass Sie eine Gegenwirkung haben, die Auswirkungen dieser Aktion
  • rückgängig machen

In meinem (Diagramm) Editor gibt es vier Stufen von Zustandsänderungen:

  • action Fragmente: dieser Teil einer größeren Aktion sind und nicht einzeln rückgängig gemacht werden oder wiederherstellbaren (Zum Beispiel der Maus zu bewegen)
  • Aktionen: ein oder mehr Aktionsfragmente, die eine sinnvolle Veränderung bilden, die rückgängig gemacht oder wiederholt werden können, die aber nicht in dem editierte Dokument reflektiert, wie auf dem Datenträger geändert (Z.B. Auswahlelemente)
  • Dokumentänderungen: eine oder mehr Aktionen, die das bearbeitete Dokument zu ändern, wie es auf der Festplatte gespeichert werden würde (Z.B. Ändern, Hinzufügen oder Löschen von Elementen)
  • Dokument speichert: der gegenwärtige Zustand des Dokuments ausdrücklich auf die Festplatte gespeichert ist - an dieser Stelle mein Editor, um die Undo-History wegwirft, so kann man nicht rückgängig Vergangenheit ein Speichern

Dies ist ein Job für dem Befehl Muster .

Hier ist ein Ausschnitt zeigt, wie SWT Undo / Redo-Operationen unterstützt. Nehmen Sie es als praktisches Beispiel (oder verwenden Sie es direkt, wenn der Editor auf SWT basiert):

SWT Undo Redo

Lesen Sie ein Buch Design Patterns: Elemente wiederverwendbarer objektorientierter Software . Soweit ich mich erinnere, gibt es ein ziemlich gutes Beispiel.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top