fix: undo manager works properly
This commit is contained in:
parent
648941706d
commit
71e1b7deff
|
@ -1,6 +1,8 @@
|
||||||
package se.lantz;
|
package se.lantz;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GraphicsDevice;
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
|
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
@ -32,8 +34,13 @@ public class PCUGameManager
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
|
||||||
MainWindow mainWindow = MainWindow.getInstance();
|
MainWindow mainWindow = MainWindow.getInstance();
|
||||||
mainWindow.setSize(1400, 850);
|
|
||||||
mainWindow.setMinimumSize(new Dimension(1300, 700));
|
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
|
||||||
|
int width = gd.getDisplayMode().getWidth();
|
||||||
|
int height = gd.getDisplayMode().getHeight();
|
||||||
|
|
||||||
|
mainWindow.setSize(Math.min(width, 1500), Math.min(height-40, 825));
|
||||||
|
mainWindow.setMinimumSize(new Dimension(Math.min(width, 1300), Math.min(height-40, 700)));
|
||||||
mainWindow.setVisible(true);
|
mainWindow.setVisible(true);
|
||||||
mainWindow.setLocationRelativeTo(null);
|
mainWindow.setLocationRelativeTo(null);
|
||||||
mainWindow.initialize();
|
mainWindow.initialize();
|
||||||
|
|
|
@ -19,6 +19,7 @@ import javax.swing.event.DocumentListener;
|
||||||
import javax.swing.text.DefaultStyledDocument;
|
import javax.swing.text.DefaultStyledDocument;
|
||||||
|
|
||||||
import se.lantz.model.InfoModel;
|
import se.lantz.model.InfoModel;
|
||||||
|
import se.lantz.util.CustomUndoPlainDocument;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
|
@ -73,7 +74,7 @@ public class DescriptionPanel extends JPanel
|
||||||
descriptionTextArea.setWrapStyleWord(true);
|
descriptionTextArea.setWrapStyleWord(true);
|
||||||
descriptionTextArea.setLineWrap(true);
|
descriptionTextArea.setLineWrap(true);
|
||||||
|
|
||||||
DefaultStyledDocument doc = new DefaultStyledDocument();
|
CustomUndoPlainDocument doc = new CustomUndoPlainDocument();
|
||||||
doc.addDocumentListener(new DocumentListener()
|
doc.addDocumentListener(new DocumentListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -147,7 +147,7 @@ public class GameDetailsBackgroundPanel extends JPanel
|
||||||
{
|
{
|
||||||
GridBagLayout gbl_settingsPanel = new GridBagLayout();
|
GridBagLayout gbl_settingsPanel = new GridBagLayout();
|
||||||
settingsPanel = new ScrollablePanel(gbl_settingsPanel);
|
settingsPanel = new ScrollablePanel(gbl_settingsPanel);
|
||||||
settingsPanel.setPreferredSize(new Dimension(1120,425));
|
settingsPanel.setPreferredSize(new Dimension(1120,400));
|
||||||
settingsPanel.setScrollableHeight(ScrollableSizeHint.STRETCH);
|
settingsPanel.setScrollableHeight(ScrollableSizeHint.STRETCH);
|
||||||
settingsPanel.setScrollableWidth(ScrollableSizeHint.STRETCH);
|
settingsPanel.setScrollableWidth(ScrollableSizeHint.STRETCH);
|
||||||
GridBagConstraints gbc_systemPanel = new GridBagConstraints();
|
GridBagConstraints gbc_systemPanel = new GridBagConstraints();
|
||||||
|
|
|
@ -26,6 +26,7 @@ import javax.swing.SwingUtilities;
|
||||||
import javax.swing.text.DefaultEditorKit;
|
import javax.swing.text.DefaultEditorKit;
|
||||||
|
|
||||||
import se.lantz.model.InfoModel;
|
import se.lantz.model.InfoModel;
|
||||||
|
import se.lantz.util.CustomUndoPlainDocument;
|
||||||
import se.lantz.util.TextComponentSupport;
|
import se.lantz.util.TextComponentSupport;
|
||||||
|
|
||||||
public class InfoPanel extends JPanel
|
public class InfoPanel extends JPanel
|
||||||
|
@ -210,6 +211,7 @@ public class InfoPanel extends JPanel
|
||||||
if (titleField == null)
|
if (titleField == null)
|
||||||
{
|
{
|
||||||
titleField = new JTextField();
|
titleField = new JTextField();
|
||||||
|
titleField.setDocument(new CustomUndoPlainDocument());
|
||||||
titleField.addKeyListener(new KeyAdapter()
|
titleField.addKeyListener(new KeyAdapter()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -273,6 +275,7 @@ public class InfoPanel extends JPanel
|
||||||
if (authorField == null)
|
if (authorField == null)
|
||||||
{
|
{
|
||||||
authorField = new JTextField();
|
authorField = new JTextField();
|
||||||
|
authorField.setDocument(new CustomUndoPlainDocument());
|
||||||
authorField.addKeyListener(new KeyAdapter()
|
authorField.addKeyListener(new KeyAdapter()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -291,6 +294,7 @@ public class InfoPanel extends JPanel
|
||||||
if (composerField == null)
|
if (composerField == null)
|
||||||
{
|
{
|
||||||
composerField = new JTextField();
|
composerField = new JTextField();
|
||||||
|
composerField.setDocument(new CustomUndoPlainDocument());
|
||||||
composerField.addKeyListener(new KeyAdapter()
|
composerField.addKeyListener(new KeyAdapter()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@ import javax.swing.SwingConstants;
|
||||||
import javax.swing.border.TitledBorder;
|
import javax.swing.border.TitledBorder;
|
||||||
|
|
||||||
import se.lantz.model.JoystickModel;
|
import se.lantz.model.JoystickModel;
|
||||||
|
import se.lantz.util.CustomUndoPlainDocument;
|
||||||
import se.lantz.util.TextComponentSupport;
|
import se.lantz.util.TextComponentSupport;
|
||||||
|
|
||||||
public class JoystickPanel extends JPanel
|
public class JoystickPanel extends JPanel
|
||||||
|
@ -256,6 +257,7 @@ public class JoystickPanel extends JPanel
|
||||||
if (configTextField == null)
|
if (configTextField == null)
|
||||||
{
|
{
|
||||||
configTextField = new JTextField();
|
configTextField = new JTextField();
|
||||||
|
configTextField.setDocument(new CustomUndoPlainDocument());
|
||||||
configTextField.setColumns(10);
|
configTextField.setColumns(10);
|
||||||
configTextField.addFocusListener(new FocusListener()
|
configTextField.addFocusListener(new FocusListener()
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,292 @@
|
||||||
|
package se.lantz.util;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.InputEvent;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.event.DocumentEvent;
|
||||||
|
import javax.swing.event.DocumentListener;
|
||||||
|
import javax.swing.event.UndoableEditEvent;
|
||||||
|
import javax.swing.event.UndoableEditListener;
|
||||||
|
import javax.swing.text.AbstractDocument;
|
||||||
|
import javax.swing.text.JTextComponent;
|
||||||
|
import javax.swing.undo.CannotRedoException;
|
||||||
|
import javax.swing.undo.CannotUndoException;
|
||||||
|
import javax.swing.undo.CompoundEdit;
|
||||||
|
import javax.swing.undo.UndoManager;
|
||||||
|
import javax.swing.undo.UndoableEdit;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This class will merge individual edits into a single larger edit.
|
||||||
|
** That is, characters entered sequentially will be grouped together and
|
||||||
|
** undone as a group. Any attribute changes will be considered as part
|
||||||
|
** of the group and will therefore be undone when the group is undone.
|
||||||
|
*/
|
||||||
|
public class CompoundUndoManager extends UndoManager implements UndoableEditListener, DocumentListener
|
||||||
|
{
|
||||||
|
private UndoManager undoManager;
|
||||||
|
private CompoundEdit compoundEdit;
|
||||||
|
private JTextComponent textComponent;
|
||||||
|
private UndoAction undoAction;
|
||||||
|
private RedoAction redoAction;
|
||||||
|
|
||||||
|
// These fields are used to help determine whether the edit is an
|
||||||
|
// incremental edit. The offset and length should increase by 1 for
|
||||||
|
// each character added or decrease by 1 for each character removed.
|
||||||
|
|
||||||
|
private int lastOffset;
|
||||||
|
private int lastLength;
|
||||||
|
|
||||||
|
public CompoundUndoManager(JTextComponent textComponent)
|
||||||
|
{
|
||||||
|
this.textComponent = textComponent;
|
||||||
|
undoManager = this;
|
||||||
|
undoAction = new UndoAction();
|
||||||
|
redoAction = new RedoAction();
|
||||||
|
textComponent.getDocument().addUndoableEditListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Add a DocumentLister before the undo is done so we can position the Caret
|
||||||
|
* correctly as each edit is undone.
|
||||||
|
*/
|
||||||
|
public void undo()
|
||||||
|
{
|
||||||
|
textComponent.getDocument().addDocumentListener(this);
|
||||||
|
super.undo();
|
||||||
|
textComponent.getDocument().removeDocumentListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Add a DocumentLister before the redo is done so we can position the Caret
|
||||||
|
* correctly as each edit is redone.
|
||||||
|
*/
|
||||||
|
public void redo()
|
||||||
|
{
|
||||||
|
textComponent.getDocument().addDocumentListener(this);
|
||||||
|
super.redo();
|
||||||
|
textComponent.getDocument().removeDocumentListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Whenever an UndoableEdit happens the edit will either be absorbed by the
|
||||||
|
* current compound edit or a new compound edit will be started
|
||||||
|
*/
|
||||||
|
public void undoableEditHappened(UndoableEditEvent e)
|
||||||
|
{
|
||||||
|
// Start a new compound edit
|
||||||
|
|
||||||
|
if (compoundEdit == null)
|
||||||
|
{
|
||||||
|
compoundEdit = startCompoundEdit(e.getEdit());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offsetChange = textComponent.getCaretPosition() - lastOffset;
|
||||||
|
int lengthChange = textComponent.getDocument().getLength() - lastLength;
|
||||||
|
|
||||||
|
// Check for an attribute change
|
||||||
|
|
||||||
|
AbstractDocument.DefaultDocumentEvent event = (AbstractDocument.DefaultDocumentEvent) e.getEdit();
|
||||||
|
|
||||||
|
if (event.getType().equals(DocumentEvent.EventType.CHANGE))
|
||||||
|
{
|
||||||
|
if (offsetChange == 0)
|
||||||
|
{
|
||||||
|
compoundEdit.addEdit(e.getEdit());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for an incremental edit or backspace.
|
||||||
|
// The Change in Caret position and Document length should both be
|
||||||
|
// either 1 or -1.
|
||||||
|
|
||||||
|
// int offsetChange = textComponent.getCaretPosition() - lastOffset;
|
||||||
|
// int lengthChange = textComponent.getDocument().getLength() - lastLength;
|
||||||
|
|
||||||
|
if (offsetChange == lengthChange && Math.abs(offsetChange) == 1)
|
||||||
|
{
|
||||||
|
compoundEdit.addEdit(e.getEdit());
|
||||||
|
lastOffset = textComponent.getCaretPosition();
|
||||||
|
lastLength = textComponent.getDocument().getLength();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not incremental edit, end previous edit and start a new one
|
||||||
|
|
||||||
|
compoundEdit.end();
|
||||||
|
compoundEdit = startCompoundEdit(e.getEdit());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Each CompoundEdit will store a group of related incremental edits (ie. each
|
||||||
|
* character typed or backspaced is an incremental edit)
|
||||||
|
*/
|
||||||
|
private CompoundEdit startCompoundEdit(UndoableEdit anEdit)
|
||||||
|
{
|
||||||
|
// Track Caret and Document information of this compound edit
|
||||||
|
|
||||||
|
lastOffset = textComponent.getCaretPosition();
|
||||||
|
lastLength = textComponent.getDocument().getLength();
|
||||||
|
|
||||||
|
// The compound edit is used to store incremental edits
|
||||||
|
|
||||||
|
compoundEdit = new MyCompoundEdit();
|
||||||
|
compoundEdit.addEdit(anEdit);
|
||||||
|
|
||||||
|
// The compound edit is added to the UndoManager. All incremental
|
||||||
|
// edits stored in the compound edit will be undone/redone at once
|
||||||
|
|
||||||
|
addEdit(compoundEdit);
|
||||||
|
|
||||||
|
undoAction.updateUndoState();
|
||||||
|
redoAction.updateRedoState();
|
||||||
|
|
||||||
|
return compoundEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Action to Undo changes to the Document. The state of the Action is
|
||||||
|
* managed by the CompoundUndoManager
|
||||||
|
*/
|
||||||
|
public Action getUndoAction()
|
||||||
|
{
|
||||||
|
return undoAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Action to Redo changes to the Document. The state of the Action is
|
||||||
|
* managed by the CompoundUndoManager
|
||||||
|
*/
|
||||||
|
public Action getRedoAction()
|
||||||
|
{
|
||||||
|
return redoAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implement DocumentListener
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
* Updates to the Document as a result of Undo/Redo will cause the Caret to be
|
||||||
|
* repositioned
|
||||||
|
*/
|
||||||
|
public void insertUpdate(final DocumentEvent e)
|
||||||
|
{
|
||||||
|
SwingUtilities.invokeLater(new Runnable()
|
||||||
|
{
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
int offset = e.getOffset() + e.getLength();
|
||||||
|
offset = Math.min(offset, textComponent.getDocument().getLength());
|
||||||
|
textComponent.setCaretPosition(offset);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeUpdate(DocumentEvent e)
|
||||||
|
{
|
||||||
|
textComponent.setCaretPosition(e.getOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changedUpdate(DocumentEvent e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyCompoundEdit extends CompoundEdit
|
||||||
|
{
|
||||||
|
public boolean isInProgress()
|
||||||
|
{
|
||||||
|
// in order for the canUndo() and canRedo() methods to work
|
||||||
|
// assume that the compound edit is never in progress
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void undo() throws CannotUndoException
|
||||||
|
{
|
||||||
|
// End the edit so future edits don't get absorbed by this edit
|
||||||
|
|
||||||
|
if (compoundEdit != null)
|
||||||
|
compoundEdit.end();
|
||||||
|
|
||||||
|
super.undo();
|
||||||
|
|
||||||
|
// Always start a new compound edit after an undo
|
||||||
|
|
||||||
|
compoundEdit = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform the Undo and update the state of the undo/redo Actions
|
||||||
|
*/
|
||||||
|
class UndoAction extends AbstractAction
|
||||||
|
{
|
||||||
|
public UndoAction()
|
||||||
|
{
|
||||||
|
putValue(Action.NAME, "Undo");
|
||||||
|
putValue(Action.SHORT_DESCRIPTION, getValue(Action.NAME));
|
||||||
|
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_U));
|
||||||
|
putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control Z"));
|
||||||
|
setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
undoManager.undo();
|
||||||
|
textComponent.requestFocusInWindow();
|
||||||
|
} catch (CannotUndoException ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUndoState();
|
||||||
|
redoAction.updateRedoState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateUndoState()
|
||||||
|
{
|
||||||
|
setEnabled(undoManager.canUndo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform the Redo and update the state of the undo/redo Actions
|
||||||
|
*/
|
||||||
|
class RedoAction extends AbstractAction
|
||||||
|
{
|
||||||
|
public RedoAction()
|
||||||
|
{
|
||||||
|
putValue(Action.NAME, "Redo");
|
||||||
|
putValue(Action.SHORT_DESCRIPTION, getValue(Action.NAME));
|
||||||
|
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_R));
|
||||||
|
putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_MASK));
|
||||||
|
setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
undoManager.redo();
|
||||||
|
textComponent.requestFocusInWindow();
|
||||||
|
} catch (CannotRedoException ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
updateRedoState();
|
||||||
|
undoAction.updateUndoState();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateRedoState()
|
||||||
|
{
|
||||||
|
setEnabled(undoManager.canRedo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package se.lantz.util;
|
||||||
|
|
||||||
|
import javax.swing.event.UndoableEditEvent;
|
||||||
|
import javax.swing.text.AttributeSet;
|
||||||
|
import javax.swing.text.BadLocationException;
|
||||||
|
import javax.swing.text.PlainDocument;
|
||||||
|
import javax.swing.undo.CompoundEdit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Document supporting undo/redo better than default
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CustomUndoPlainDocument extends PlainDocument
|
||||||
|
{
|
||||||
|
private CompoundEdit compoundEdit;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fireUndoableEditUpdate(UndoableEditEvent e)
|
||||||
|
{
|
||||||
|
if (compoundEdit == null)
|
||||||
|
{
|
||||||
|
super.fireUndoableEditUpdate(e);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
compoundEdit.addEdit(e.getEdit());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replace(int offset, int length, String text, AttributeSet attrs) throws BadLocationException
|
||||||
|
{
|
||||||
|
if (length == 0)
|
||||||
|
{
|
||||||
|
super.replace(offset, length, text, attrs);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
compoundEdit = new CompoundEdit();
|
||||||
|
super.fireUndoableEditUpdate(new UndoableEditEvent(this, compoundEdit));
|
||||||
|
super.replace(offset, length, text, attrs);
|
||||||
|
compoundEdit.end();
|
||||||
|
compoundEdit = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,8 @@ package se.lantz.util;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.InputEvent;
|
import java.awt.event.InputEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -10,9 +12,12 @@ import javax.swing.AbstractAction;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
import javax.swing.event.DocumentEvent;
|
||||||
import javax.swing.event.UndoableEditEvent;
|
import javax.swing.event.UndoableEditEvent;
|
||||||
import javax.swing.event.UndoableEditListener;
|
import javax.swing.event.UndoableEditListener;
|
||||||
|
import javax.swing.text.AbstractDocument.DefaultDocumentEvent;
|
||||||
import javax.swing.text.DefaultEditorKit;
|
import javax.swing.text.DefaultEditorKit;
|
||||||
|
import javax.swing.text.Document;
|
||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
import javax.swing.text.TextAction;
|
import javax.swing.text.TextAction;
|
||||||
import javax.swing.undo.CannotRedoException;
|
import javax.swing.undo.CannotRedoException;
|
||||||
|
@ -24,7 +29,7 @@ public class TextComponentSupport
|
||||||
{
|
{
|
||||||
public final static String UNDO_ACTION = "Undo";
|
public final static String UNDO_ACTION = "Undo";
|
||||||
public final static String REDO_ACTION = "Redo";
|
public final static String REDO_ACTION = "Redo";
|
||||||
|
|
||||||
private static List<UndoManager> managerList = new ArrayList<>();
|
private static List<UndoManager> managerList = new ArrayList<>();
|
||||||
|
|
||||||
private TextComponentSupport()
|
private TextComponentSupport()
|
||||||
|
@ -51,17 +56,17 @@ public class TextComponentSupport
|
||||||
addAction(popupMenu, new DefaultEditorKit.CutAction(), KeyEvent.VK_X, "Cut");
|
addAction(popupMenu, new DefaultEditorKit.CutAction(), KeyEvent.VK_X, "Cut");
|
||||||
addAction(popupMenu, new DefaultEditorKit.CopyAction(), KeyEvent.VK_C, "Copy");
|
addAction(popupMenu, new DefaultEditorKit.CopyAction(), KeyEvent.VK_C, "Copy");
|
||||||
addAction(popupMenu, new DefaultEditorKit.PasteAction(), KeyEvent.VK_V, "Paste");
|
addAction(popupMenu, new DefaultEditorKit.PasteAction(), KeyEvent.VK_V, "Paste");
|
||||||
|
|
||||||
tc.setComponentPopupMenu(popupMenu);
|
tc.setComponentPopupMenu(popupMenu);
|
||||||
makeUndoable(popupMenu, tc);
|
makeUndoable(popupMenu, tc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearUndoManagers()
|
public static void clearUndoManagers()
|
||||||
{
|
{
|
||||||
for (UndoManager undoManager : managerList)
|
for (UndoManager undoManager : managerList)
|
||||||
{
|
{
|
||||||
undoManager.discardAllEdits();
|
undoManager.discardAllEdits();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,17 +76,26 @@ public class TextComponentSupport
|
||||||
managerList.add(undoMgr);
|
managerList.add(undoMgr);
|
||||||
|
|
||||||
// Add listener for undoable events
|
// Add listener for undoable events
|
||||||
pTextComponent.getDocument().addUndoableEditListener(undoMgr);
|
// pTextComponent.getDocument().addUndoableEditListener(undoMgr);
|
||||||
// pTextComponent.getDocument().addUndoableEditListener(new UndoableEditListener()
|
pTextComponent.getDocument().addUndoableEditListener(new UndoableEditListener()
|
||||||
// {
|
{
|
||||||
// public void undoableEditHappened(UndoableEditEvent evt)
|
public void undoableEditHappened(UndoableEditEvent evt)
|
||||||
// {
|
{
|
||||||
// if (evt.getEdit().isSignificant())
|
// DefaultDocumentEvent event = (DefaultDocumentEvent) evt.getEdit();
|
||||||
|
//
|
||||||
|
// System.out.println(
|
||||||
|
// "EVENT TYPE=" + event.getType() + ", LENGTH=" + event.getLength() + ", OFFSET=" + event.getOffset());
|
||||||
|
//
|
||||||
|
// if (event.getType().equals(DocumentEvent.EventType.REMOVE) && event.getLength() > 0 && event.getOffset() == 0)
|
||||||
// {
|
// {
|
||||||
// undoMgr.addEdit(evt.getEdit());
|
// //undoMgr.discardAllEdits();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
undoMgr.addEdit(evt.getEdit());
|
||||||
// }
|
// }
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
|
|
||||||
// Add undo/redo actions
|
// Add undo/redo actions
|
||||||
AbstractAction undoAction = new AbstractAction(UNDO_ACTION)
|
AbstractAction undoAction = new AbstractAction(UNDO_ACTION)
|
||||||
|
@ -93,7 +107,7 @@ public class TextComponentSupport
|
||||||
if (undoMgr.canUndo())
|
if (undoMgr.canUndo())
|
||||||
{
|
{
|
||||||
undoMgr.undo();
|
undoMgr.undo();
|
||||||
//this.setEnabled(undoMgr.canUndo());
|
// this.setEnabled(undoMgr.canUndo());
|
||||||
}
|
}
|
||||||
} catch (CannotUndoException e)
|
} catch (CannotUndoException e)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +116,8 @@ public class TextComponentSupport
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
pTextComponent.getActionMap().put(UNDO_ACTION, undoAction);
|
pTextComponent.getActionMap().put(UNDO_ACTION, undoAction);
|
||||||
undoAction.putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK));
|
undoAction.putValue(AbstractAction.ACCELERATOR_KEY,
|
||||||
|
KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK));
|
||||||
AbstractAction redoAction = new AbstractAction(REDO_ACTION)
|
AbstractAction redoAction = new AbstractAction(REDO_ACTION)
|
||||||
{
|
{
|
||||||
public void actionPerformed(ActionEvent evt)
|
public void actionPerformed(ActionEvent evt)
|
||||||
|
@ -112,7 +127,7 @@ public class TextComponentSupport
|
||||||
if (undoMgr.canRedo())
|
if (undoMgr.canRedo())
|
||||||
{
|
{
|
||||||
undoMgr.redo();
|
undoMgr.redo();
|
||||||
//this.setEnabled(undoMgr.canRedo());
|
// this.setEnabled(undoMgr.canRedo());
|
||||||
}
|
}
|
||||||
} catch (CannotRedoException e)
|
} catch (CannotRedoException e)
|
||||||
{
|
{
|
||||||
|
@ -121,7 +136,8 @@ public class TextComponentSupport
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
pTextComponent.getActionMap().put(REDO_ACTION, redoAction);
|
pTextComponent.getActionMap().put(REDO_ACTION, redoAction);
|
||||||
redoAction.putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK));
|
redoAction.putValue(AbstractAction.ACCELERATOR_KEY,
|
||||||
|
KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK));
|
||||||
// Create keyboard accelerators for undo/redo actions (Ctrl+Z/Ctrl+Y)
|
// Create keyboard accelerators for undo/redo actions (Ctrl+Z/Ctrl+Y)
|
||||||
pTextComponent.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK), UNDO_ACTION);
|
pTextComponent.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK), UNDO_ACTION);
|
||||||
pTextComponent.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK), REDO_ACTION);
|
pTextComponent.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK), REDO_ACTION);
|
||||||
|
|
Loading…
Reference in New Issue