/* * $Id$ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc * * Copyright (c) 2000-2012 Stephane GALLAND. * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, * Universite de Technologie de Belfort-Montbeliard. * Copyright (c) 2013-2016 The original authors, and other authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.arakhne.afc.ui.undo ; import java.util.Iterator; import java.util.LinkedList; import org.arakhne.afc.util.ListenerCollection; import org.arakhne.afc.vmutil.locale.Locale; /** Manager of undoable actions. * * @author $Author: sgalland$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ * @deprecated see JavaFX API */ @Deprecated public class DefaultUndoManager implements UndoManager { private final ListenerCollection<UndoListener> listeners = new ListenerCollection<>(); private final LinkedList<Undoable> undoes = new LinkedList<>(); private final LinkedList<Undoable> redoes = new LinkedList<>(); private int limit = 100; /** */ public DefaultUndoManager() { // } @Override public synchronized final void setLimit(int l) { if (l!=this.limit) { this.limit = l; } } @Override public synchronized final int getLimit() { return this.limit; } @Override public void addUndoListener(UndoListener l) { this.listeners.add(UndoListener.class,l); } @Override public void removeUndoListener(UndoListener l) { this.listeners.remove(UndoListener.class,l); } /** * Notifies listeners. */ protected void fireChange() { for(UndoListener listener : this.listeners.getListeners(UndoListener.class)) { listener.undoListChanged(this); } } @Override public boolean add(Undoable action) { synchronized(this) { if (action==null || this.limit==0) return false; Iterator<Undoable> iterator; Undoable u; // Clear the list of the redoable actions iterator = this.redoes.iterator(); while (iterator.hasNext()) { u = iterator.next(); u.die(); iterator.remove(); } // Remove the too old undoable actions if (this.limit>0) { while (this.undoes.size()>=this.limit) { u = this.undoes.removeFirst(); u.die(); } } // Add the new action. this.undoes.addLast(action); if (action instanceof UndoableGroup) { ((UndoableGroup)action).end(); } } fireChange(); return true; } @Override public synchronized void undo() { synchronized(this) { if (this.undoes.isEmpty()) throw new IllegalStateException(); Undoable u = this.undoes.removeLast(); u.undo(); this.redoes.addFirst(u); } fireChange(); } @Override public synchronized boolean canUndo() { return !this.undoes.isEmpty(); } @Override public void redo() { synchronized(this) { if (this.redoes.isEmpty()) throw new IllegalStateException(); Undoable u = this.redoes.removeFirst(); u.redo(); this.undoes.addLast(u); } fireChange(); } @Override public synchronized boolean canRedo() { return !this.redoes.isEmpty(); } @Override public synchronized void discardAll() { boolean changed = false; synchronized(this) { Iterator<Undoable> iterator; Undoable u; iterator = this.redoes.iterator(); while (iterator.hasNext()) { u = iterator.next(); u.die(); iterator.remove(); changed = true; } iterator = this.undoes.iterator(); while (iterator.hasNext()) { u = iterator.next(); u.die(); iterator.remove(); changed = false; } } if (changed) { fireChange(); } } @Override public synchronized String getUndoPresentationName() { if (canUndo()) return Locale.getString("UNDO", this.undoes.getLast().getPresentationName()); //$NON-NLS-1$ return Locale.getString("NO_UNDO"); //$NON-NLS-1$ } @Override public synchronized String getRedoPresentationName() { if (canRedo()) return Locale.getString("REDO", this.redoes.getFirst().getPresentationName()); //$NON-NLS-1$ return Locale.getString("NO_REDO"); //$NON-NLS-1$ } }