简体   繁体   English

Java中不可撤消的文本区域

[英]Undoable Text Area in Java

I'm just approaching the programming in java.... I'd like to create a small Text Editor (Windows Notepad clone...). 我正在使用Java进行编程。...我想创建一个小的文本编辑器(Windows记事本克隆...)。

I'm searching for a Class that extend the JTextArea implementing the undo & redo actions. 我正在寻找一个扩展JTextArea的类,该类实现了撤消和重做操作。 I found a code that match my needs, and I tried to adapt it to my purposes. 我找到了满足自己需求的代码,并尝试使其适应我的目的。

Here's the code: 这是代码:

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) {
    }
}

Using Accellerators Key CTRL + Z , CTRL + Y while typing in the object, there's no problem.... but methods undo() and redo() added by me for use this actions from menuItem objetcs, don't work... 在键入对象时使用Accellerators键CTRL + ZCTRL + 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();
}
}

Any suggestions? 有什么建议么? Sorry for my bad english... 对不起,我的英语不好...

Thanks! 谢谢!

The problem is likely due to the code adding and removing the UndoManager upon focusGained and focusLost events: 该问题可能是由于代码在focusGained和focusLost事件上添加和删除了UndoManager导致的:

public void focusGained(FocusEvent fe) {
    createUndoMananger();
}

public void focusLost(FocusEvent fe) {
    removeUndoMananger();
}

When you click on the menu, the text area temporarily loses the focus, whereupon the UndoManager is discarded and then a new instance is created. 当您单击菜单上时,文本区域会暂时失去焦点,随后将放弃UndoManager,然后创建一个新实例。 The new instance doesn't know about previous undoable edit events, and thus undo and redo do not work. 新实例不知道以前的可撤消编辑事件,因此撤消和重做不起作用。

I suggest creating the UndoManager once and keeping it attached to the document until the GUI is disposed (ie until the dialog / window is closed). 我建议一次创建UndoManager并将其附加在文档上,直到释放GUI(即关闭对话框/窗口)为止。

Solved! 解决了! I realized that the creation of the UndoManager was linked to the event of focusGained() of my JTextArea extended object. 我意识到UndoManager的创建与JTextArea扩展对象的focusGained()事件相关联。 So, when I was selecting action by menuItem, I lose the focus and the UndoManager destroyed. 因此,当我通过menuItem选择操作时,我失去了焦点,UndoManager被破坏了。

I changed the method createUndoMananger from private to public, and Invoked outside the class... 我将createUndoMananger方法从私有更改为公共,并在课程外调用了...

(..)
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()");
}

(...) (...)

Thanks anyway!!! 不管怎么说,还是要谢谢你!!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM