📄 undomanager.java
字号:
* @param edit the last editing action to be undone. */ protected void undoTo(UndoableEdit edit) throws CannotUndoException { UndoableEdit cur; if (!edits.contains(edit)) throw new CannotUndoException(); while (true) { indexOfNextAdd -= 1; cur = (UndoableEdit) edits.get(indexOfNextAdd); cur.undo(); if (cur == edit) return; } } /** * Redoes all editing actions in the same order as they were * added to this UndoManager, up to the specified action. * * @param edit the last editing action to be redone. */ protected void redoTo(UndoableEdit edit) throws CannotRedoException { UndoableEdit cur; if (!edits.contains(edit)) throw new CannotRedoException(); while (true) { cur = (UndoableEdit) edits.get(indexOfNextAdd); indexOfNextAdd += 1; cur.redo(); if (cur == edit) return; } } /** * Undoes or redoes the last action. If the last action has already * been undone, it will be re-done, and vice versa. * * <p>This is useful for applications that do not present a separate * undo and redo facility, but just have a single menu item for * undoing and redoing the very last action. Such applications will * use an <code>UndoManager</code> whose <code>limit</code> is 1. */ public synchronized void undoOrRedo() throws CannotRedoException, CannotUndoException { if (indexOfNextAdd == edits.size()) undo(); else redo(); } /** * Determines whether it would be possible to either undo or redo * this editing action. * * <p>This is useful for applications that do not present a separate * undo and redo facility, but just have a single menu item for * undoing and redoing the very last action. Such applications will * use an <code>UndoManager</code> whose <code>limit</code> is 1. * * @return <code>true</code> to indicate that this action can be * undone or redone; <code>false</code> if neither is possible at * the current time. */ public synchronized boolean canUndoOrRedo() { return indexOfNextAdd == edits.size() ? canUndo() : canRedo(); } /** * Undoes one significant edit action. If insignificant actions have * been posted after the last signficant action, the insignificant * ones will be undone first. * * <p>However, if {@link #end()} has been called on this * UndoManager, it will behave like a normal {@link * CompoundEdit}. In this case, all actions will be undone in * reverse order of addition. Typical applications will never call * {@link #end()} on their <code>UndoManager</code>. * * @throws CannotUndoException if no action can be undone. * * @see #canUndo() * @see #redo() * @see #undoOrRedo() */ public synchronized void undo() throws CannotUndoException { if (!isInProgress()) { super.undo(); return; } UndoableEdit edit = editToBeUndone(); if (edit == null) throw new CannotUndoException(); undoTo(edit); } /** * Determines whether it would be possible to undo this editing * action. * * @return <code>true</code> to indicate that this action can be * undone; <code>false</code> otherwise. * * @see #undo() * @see #canRedo() * @see #canUndoOrRedo() */ public synchronized boolean canUndo() { UndoableEdit edit; if (!isInProgress()) return super.canUndo(); edit = editToBeUndone(); return edit != null && edit.canUndo(); } /** * Redoes one significant edit action. If insignificant actions have * been posted in between, the insignificant ones will be redone * first. * * <p>However, if {@link #end()} has been called on this * UndoManager, it will behave like a normal {@link * CompoundEdit}. In this case, <em>all</em> actions will be redone * in order of addition. Typical applications will never call {@link * #end()} on their <code>UndoManager</code>. * * @throws CannotRedoException if no action can be redone. * * @see #canRedo() * @see #redo() * @see #undoOrRedo() */ public synchronized void redo() throws CannotRedoException { if (!isInProgress()) { super.redo(); return; } UndoableEdit edit = editToBeRedone(); if (edit == null) throw new CannotRedoException(); redoTo(edit); } /** * Determines whether it would be possible to redo this editing * action. * * @return <code>true</code> to indicate that this action can be * redone; <code>false</code> otherwise. * * @see #redo() * @see #canUndo() * @see #canUndoOrRedo() */ public synchronized boolean canRedo() { UndoableEdit edit; if (!isInProgress()) return super.canRedo(); edit = editToBeRedone(); return edit != null && edit.canRedo(); } /** * Registers an undoable editing action with this UndoManager. If * the capacity <code>limit</code> is reached, the oldest action * will be discarded (and receives a {@linkplain UndoableEdit#die() * die message}. Equally, any actions that were undone (but not re-done) * will be discarded, too. * * @param edit the editing action that is added to this UndoManager. * * @return <code>true</code> if <code>edit</code> could be * incorporated; <code>false</code> if <code>edit</code> has not * been incorporated because {@link #end()} has already been called * on this <code>UndoManager</code>. */ public synchronized boolean addEdit(UndoableEdit edit) { boolean result; // Discard any edits starting at indexOfNextAdd. trimEdits(indexOfNextAdd, edits.size() - 1); result = super.addEdit(edit); indexOfNextAdd = edits.size(); trimForLimit(); return result; } /** * Calculates a localized text for presenting the undo or redo * action to the user, for example in the form of a menu command. * * <p>This is useful for applications that do not present a separate * undo and redo facility, but just have a single menu item for * undoing and redoing the very last action. Such applications will * use an <code>UndoManager</code> whose <code>limit</code> is 1. * * @return the redo presentation name if the last action has already * been undone, or the undo presentation name otherwise. * * @see #getUndoPresentationName() * @see #getRedoPresentationName() */ public synchronized String getUndoOrRedoPresentationName() { if (indexOfNextAdd == edits.size()) return getUndoPresentationName(); else return getRedoPresentationName(); } /** * Calculates a localized text for presenting the undo action * to the user, for example in the form of a menu command. */ public synchronized String getUndoPresentationName() { UndoableEdit edit; if (!isInProgress()) return super.getUndoPresentationName(); edit = editToBeUndone(); if (edit == null) return UIManager.getString("AbstractUndoableEdit.undoText"); else return edit.getUndoPresentationName(); } /** * Calculates a localized text for presenting the redo action * to the user, for example in the form of a menu command. */ public synchronized String getRedoPresentationName() { UndoableEdit edit; if (!isInProgress()) return super.getRedoPresentationName(); edit = editToBeRedone(); if (edit == null) return UIManager.getString("AbstractUndoableEdit.redoText"); else return edit.getRedoPresentationName(); } /** * Registers the edit action of an {@link UndoableEditEvent} * with this UndoManager. * * <p><b>Thread Safety:</b> This method may safely be invoked from * concurrent threads. The caller does not need to perform external * synchronization. This means that {@link * javax.swing.event.UndoableEditEvent} sources do not need to broadcast * their events from inside the Swing worker thread. * * @param event the event whose <code>edit</code> will be * passed to {@link #addEdit}. * * @see UndoableEditEvent#getEdit() * @see #addEdit */ public void undoableEditHappened(UndoableEditEvent event) { // Note that this method does not need to be synchronized, // because addEdit will obtain and release the mutex. addEdit(event.getEdit()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -