Undo/Redo w Javie

0

W swoim programie chciałem dołączyć funkcję undo i redo. Ponieważ nigdy czegoś takiego nie robiłem poszukałem w internecie i znalazłem następujący art http://www.algosome.com/articles/implementing-undo-redo-java.html
Problem w tym że dziwnie to działa bo podaję na manager tę nieszczęsną wartość 2 więc i potem wykonuję undo więc logika podpowiada że powinno wypisać 1 a nie dwa. Czy ja czegoś tu nie rozumiem ?

0

Jeżeli masz już określone, że chcesz w ten sposób robić np. z polem tekstowym, to wystarczy naszykować jakąś tablicę klasy Document. Jeśli chcesz zapamiętywać np. 50 zmian, klasę robisz 50-elementową. Po każdej zmianie, w indeksie 0 tablicy wstawiasz nowy obiekt klasy Document wyciągnięty z pola tekstowego, pozostałe przesuwasz, a ostatni kasujesz. Możesz zrobić tak, że w przypadku edycji tekstu każdą dłuższą przerwę w pisaniu (np. 3 sekundy) lub pojawienie się znaku (przecinka, kropki, średnika) uznać za zakończenie aktualnej edycji i wykonanie tego przesunięcia. Później, w razie cofania edycji, pobierasz te poprzednie elementy tablicy, a "usunięte" zapisujesz w innej, tymczasowej. Gdy użytkownik postanowi przywrócić cofnięte, skorzysta z tymczasowej tablicy, a jeżeli po cofnięciu wykona jakąś edycję, to tymczasowa tablica zmienia się w null.

To jest przykład z polem tekstowym, w praktyce możesz zrobić coś podobnego praktycznie wszędzie, nie musząc się bawić w tworzenie jakichś interfejsów i klas implementujących te interfejsy.

0

Jako że muszę śledzić nie pole tekstowe a listę elementów to standardowe rozwiązania ze swinga mnie nie urządzają. Poza tym nie korzystam ze swinga tylko z JavaFX. Przysiadłem i udało mi się naklepać następującego twora.

public class ChangeManager<K> {
    int size = 0;
    Node<K> root;
    Node<K> current;

    public ChangeManager(K item) {
        size++;
        root = new Node<>(null, null, item);
        current = root;
    }
    
    public void addChange(K item){
        size++;
        Node<K> tep  = current;
        current = new Node<>(tep, null, item);
        tep.nastepny = current;
    }
    
    public boolean canUndo(){
        if(current.poprzedni!=null)return true;
        return false;
    }
    
        public boolean canRedo(){
        if(current.nastepny!=null)return true;
        return false;
    }
        
    public K undo(){
        if(canUndo()){
            size--;
            current = current.poprzedni;
            return current.obiekt;
        }else{
            throw new UnsupportedOperationException("Nothing to undo");
        }
    }
    public K redo(){
        if(canRedo()){
            size++;
            current = current.nastepny;
            return current.obiekt;
        }else{
            throw new UnsupportedOperationException("Nothing to redo");
        }
    }
    public int getSize(){
        return size;
    }
    private class Node<K>{
        Node<K> poprzedni;
        Node<K> nastepny;
        K obiekt;

        public Node(Node<K> poprzedni, Node<K> nastepny, K obiekt) {
            this.poprzedni = poprzedni;
            this.nastepny = nastepny;
            this.obiekt = obiekt;
        }
    }
}

Brakuje jeszcze metody do przycinania listy ale to chyba każdy sobie napisze. Mam nadzieję że komuś się przyda w przyszłości.

1 użytkowników online, w tym zalogowanych: 0, gości: 1