Java 中的可撤消文本区域
Undoable Text Area in Java
我刚刚开始学习 java 中的编程...我想创建一个小型文本编辑器(Windows 记事本克隆...)。
我正在寻找 Class 扩展 JTextArea 实现撤消和重做操作。我找到了符合我需要的代码,并尝试根据我的目的对其进行调整。
代码如下:
import java.awt.Toolkit;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JTextArea;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
class UndoableTextArea extends JTextArea implements UndoableEditListener, FocusListener, KeyListener
{
private static final long serialVersionUID = 1L;
private UndoManager m_undoManager;
public UndoableTextArea() {
this(new String());
}
public UndoableTextArea(String text) {
super(text);
getDocument().addUndoableEditListener(this);
this.addKeyListener(this);
this.addFocusListener(this);
}
private void createUndoMananger() {
m_undoManager = new UndoManager();
m_undoManager.setLimit(50);
}
private void removeUndoMananger() {
m_undoManager.end();
}
public void focusGained(FocusEvent fe) {
createUndoMananger();
}
public void focusLost(FocusEvent fe) {
removeUndoMananger();
}
public void undo()
{
try {
m_undoManager.undo();
} catch (CannotUndoException cue) {
Toolkit.getDefaultToolkit().beep();
}
}
public void redo()
{
try {
m_undoManager.redo();
} catch (CannotRedoException cue) {
Toolkit.getDefaultToolkit().beep();
}
}
public void undoableEditHappened(UndoableEditEvent e) {
m_undoManager.addEdit(e.getEdit());
}
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_Z) && (e.isControlDown())) {
try {
m_undoManager.undo();
} catch (CannotUndoException cue) {
Toolkit.getDefaultToolkit().beep();
}
}
if ((e.getKeyCode() == KeyEvent.VK_Y) && (e.isControlDown())) {
try {
m_undoManager.redo();
} catch (CannotRedoException cue) {
Toolkit.getDefaultToolkit().beep();
}
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
使用加速键 CTRL+Z,CTRL+Y 在输入对象时没有问题....但是我添加的方法 undo()
和 redo()
用于使用 menuItem objetcs 中的此操作,不起作用...
(...)
menuItem15 = new JMenuItem("Undo");
menuItem16 = new JMenuItem("Redo");
(...)
public void actionPerformed(ActionEvent e)
{
//Undo
if (e.getSource() == menuItem15)
{
textArea1.undo();
}
//Redo
if (e.getSource() == menuItem16)
{
textArea1.redo();
}
}
有什么建议吗?
抱歉我的英语不好...
谢谢!
问题可能是由于代码在 focusGained 和 focusLost 事件上添加和删除 UndoManager 造成的:
public void focusGained(FocusEvent fe) {
createUndoMananger();
}
public void focusLost(FocusEvent fe) {
removeUndoMananger();
}
当你点击菜单时,文本区域暂时失去焦点,UndoManager被丢弃,然后创建一个新的实例。新实例不知道以前的可撤消编辑事件,因此撤消和重做不起作用。
我建议创建一次 UndoManager 并将其附加到文档,直到 GUI 被处理(即直到对话框/window 关闭)。
已解决!
我意识到 UndoManager 的创建与我的 JTextArea 扩展对象的 focusGained() 事件相关联。因此,当我通过 menuItem 选择操作时,我失去了焦点并且 UndoManager 被销毁了。
我将方法 createUndoMananger 从私有更改为 public,并在 class...
外部调用
(..)
public void createUndoMananger() {
m_undoManager = new UndoManager();
m_undoManager.setLimit(50);
}
public void removeUndoMananger() {
m_undoManager.end();
}
public void focusGained(FocusEvent fe) {
//createUndoMananger();
//System.out.println("focusGained()");
}
public void focusLost(FocusEvent fe) {
//removeUndoMananger();
//System.out.println("focusLost()");
}
(...)
还是谢谢!!!
我刚刚开始学习 java 中的编程...我想创建一个小型文本编辑器(Windows 记事本克隆...)。
我正在寻找 Class 扩展 JTextArea 实现撤消和重做操作。我找到了符合我需要的代码,并尝试根据我的目的对其进行调整。
代码如下:
import java.awt.Toolkit;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JTextArea;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
class UndoableTextArea extends JTextArea implements UndoableEditListener, FocusListener, KeyListener
{
private static final long serialVersionUID = 1L;
private UndoManager m_undoManager;
public UndoableTextArea() {
this(new String());
}
public UndoableTextArea(String text) {
super(text);
getDocument().addUndoableEditListener(this);
this.addKeyListener(this);
this.addFocusListener(this);
}
private void createUndoMananger() {
m_undoManager = new UndoManager();
m_undoManager.setLimit(50);
}
private void removeUndoMananger() {
m_undoManager.end();
}
public void focusGained(FocusEvent fe) {
createUndoMananger();
}
public void focusLost(FocusEvent fe) {
removeUndoMananger();
}
public void undo()
{
try {
m_undoManager.undo();
} catch (CannotUndoException cue) {
Toolkit.getDefaultToolkit().beep();
}
}
public void redo()
{
try {
m_undoManager.redo();
} catch (CannotRedoException cue) {
Toolkit.getDefaultToolkit().beep();
}
}
public void undoableEditHappened(UndoableEditEvent e) {
m_undoManager.addEdit(e.getEdit());
}
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_Z) && (e.isControlDown())) {
try {
m_undoManager.undo();
} catch (CannotUndoException cue) {
Toolkit.getDefaultToolkit().beep();
}
}
if ((e.getKeyCode() == KeyEvent.VK_Y) && (e.isControlDown())) {
try {
m_undoManager.redo();
} catch (CannotRedoException cue) {
Toolkit.getDefaultToolkit().beep();
}
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
使用加速键 CTRL+Z,CTRL+Y 在输入对象时没有问题....但是我添加的方法 undo()
和 redo()
用于使用 menuItem objetcs 中的此操作,不起作用...
(...)
menuItem15 = new JMenuItem("Undo");
menuItem16 = new JMenuItem("Redo");
(...)
public void actionPerformed(ActionEvent e)
{
//Undo
if (e.getSource() == menuItem15)
{
textArea1.undo();
}
//Redo
if (e.getSource() == menuItem16)
{
textArea1.redo();
}
}
有什么建议吗? 抱歉我的英语不好...
谢谢!
问题可能是由于代码在 focusGained 和 focusLost 事件上添加和删除 UndoManager 造成的:
public void focusGained(FocusEvent fe) {
createUndoMananger();
}
public void focusLost(FocusEvent fe) {
removeUndoMananger();
}
当你点击菜单时,文本区域暂时失去焦点,UndoManager被丢弃,然后创建一个新的实例。新实例不知道以前的可撤消编辑事件,因此撤消和重做不起作用。
我建议创建一次 UndoManager 并将其附加到文档,直到 GUI 被处理(即直到对话框/window 关闭)。
已解决! 我意识到 UndoManager 的创建与我的 JTextArea 扩展对象的 focusGained() 事件相关联。因此,当我通过 menuItem 选择操作时,我失去了焦点并且 UndoManager 被销毁了。
我将方法 createUndoMananger 从私有更改为 public,并在 class...
外部调用(..)
public void createUndoMananger() {
m_undoManager = new UndoManager();
m_undoManager.setLimit(50);
}
public void removeUndoMananger() {
m_undoManager.end();
}
public void focusGained(FocusEvent fe) {
//createUndoMananger();
//System.out.println("focusGained()");
}
public void focusLost(FocusEvent fe) {
//removeUndoMananger();
//System.out.println("focusLost()");
}
(...)
还是谢谢!!!