I\'m using an UndoManager to capture changes in my JTextArea.
The method setText() however deletes everything and then pastes
By default javax.swing.undo.UndoManager retains each undoable edit, including the one that removes of the original text (your step three). Individual edits are inaccessible, but you can group edits using the approach cited here. Some additional notes on your example:
For better cross-platform results, use getMenuShortcutKeyMask() as suggested here.
Use a layout; if necessary, invoke setSize() after pack(), as shown here.
Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
Code:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.Document;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
@SuppressWarnings("serial")
public class JTextComponentSetTextUndoEvent extends JFrame {
private static final int MASK
= Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private JTextArea area = new JTextArea();
private UndoManager undoManager = new UndoManager();
public JTextComponentSetTextUndoEvent() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
area.setText("Test");
add(area);
JButton btnSettext = new JButton("setText()");
btnSettext.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
area.setText("stackoverflow.com");
}
});
add(btnSettext, BorderLayout.PAGE_END);
Document doc = area.getDocument();
doc.addUndoableEditListener(new UndoableEditListener() {
@Override
public void undoableEditHappened(UndoableEditEvent e) {
undoManager.addEdit(e.getEdit());
System.out.println(e);
}
});
area.getActionMap().put("Undo", new AbstractAction("Undo") {
@Override
public void actionPerformed(ActionEvent evt) {
try {
if (undoManager.canUndo()) {
undoManager.undo();
}
} catch (CannotUndoException e) {
System.out.println(e);
}
}
});
area.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, MASK), "Undo");
area.getActionMap().put("Redo", new AbstractAction("Redo") {
@Override
public void actionPerformed(ActionEvent evt) {
try {
if (undoManager.canRedo()) {
undoManager.redo();
}
} catch (CannotRedoException e) {
System.out.println(e);
}
}
});
area.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Y,MASK), "Redo");
pack();
setSize(320, 240);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new JTextComponentSetTextUndoEvent().setVisible(true);
}
});
}
}