划词......
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用Java来实现编辑器的Undo Redo功能

Posted on 2007-08-14 12:11  王君  阅读(599)  评论(0编辑  收藏  举报
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JEditorPane;
import javax.swing.KeyStroke;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.JTextComponent;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;

/**
* UndoWrapper is responsible for adding undo and redo support to text components.
* @author Antonio Vieiro (antonio@antonioshome.net), $Author: $
* @version $Revision: $
*/
public class UndoWrapper
implements UndoableEditListener
{
private UndoManager undoManager;
private UndoAction undoAction;
private RedoAction redoAction;
private JEditorPane textComponent;

/**
* Creates a new instance of UndoWrapper
*/
public UndoWrapper( JEditorPane aComponent )
{
textComponent = aComponent;
undoManager = new UndoManager();
undoAction = new UndoAction();
redoAction = new RedoAction();
textComponent.getDocument().addUndoableEditListener( this );
textComponent.getInputMap().put( (KeyStroke) undoAction.getValue(
Action.ACCELERATOR_KEY), "undo" );
textComponent.getInputMap().put( (KeyStroke) redoAction.getValue(
Action.ACCELERATOR_KEY), "redo" );
textComponent.getActionMap().put( "undo", undoAction );
textComponent.getActionMap().put( "redo", redoAction );
}

public void undoableEditHappened(UndoableEditEvent e)
{
undoManager.addEdit( e.getEdit() );
undoAction.updateUndoState();
redoAction.updateRedoState();
}

/**
* UndoAction is the Action responsible for handling the undo operation.
*/
class UndoAction
extends AbstractAction
{
public UndoAction()
{
super( "Cannot undo" ); // TODO: I18N
setEnabled( false );
putValue( Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl Z") );
}

public void actionPerformed(ActionEvent e)
{
try
{
undoManager.undo();
}
catch( CannotUndoException cue )
{
// TODO: Use logging?
cue.printStackTrace( System.err );
}
updateUndoState();
redoAction.updateRedoState();
}

void updateUndoState()
{
if ( undoManager.canUndo() )
{
setEnabled( true );
putValue( Action.NAME, "Undo" ); // TODO I18N
}
else
{
setEnabled( false );
putValue( Action.NAME, "Cannot undo" ); // TODO I18N
}
}
}

/**
* RedoAction is the Action responsible for handling the redo operation.
*/
class RedoAction
extends AbstractAction
{
public RedoAction()
{
super( "Cannot redo" ); // TODO I18N
setEnabled( false );
putValue( Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl Y") );
}
public void actionPerformed(ActionEvent e)
{
try
{
undoManager.redo();
}
catch( CannotRedoException cre )
{
// TODO: Use logging?
cre.printStackTrace( System.err );
}
updateRedoState();
undoAction.updateUndoState();
}

void updateRedoState()
{
if ( undoManager.canRedo() )
{
setEnabled( true );
putValue( Action.NAME, "Redo" ); // TODO I18N
}
else
{
setEnabled( false );
putValue( Action.NAME, "Cannot redo" ); // TODO I18N
}
}
}

UndoAction getUndoAction()
{
return undoAction;
}

RedoAction getRedoAction()
{
return redoAction;
}
}