簡體   English   中英

Java中不可撤消的文本區域

[英]Undoable Text Area in Java

我正在使用Java進行編程。...我想創建一個小的文本編輯器(Windows記事本克隆...)。

我正在尋找一個擴展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) {
    }
}

在鍵入對象時使用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();
}
}

有什么建議么? 對不起,我的英語不好...

謝謝!

該問題可能是由於代碼在focusGained和focusLost事件上添加和刪除了UndoManager導致的:

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

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

當您單擊菜單上時,文本區域會暫時失去焦點,隨后將放棄UndoManager,然后創建一個新實例。 新實例不知道以前的可撤消編輯事件,因此撤消和重做不起作用。

我建議一次創建UndoManager並將其附加在文檔上,直到釋放GUI(即關閉對話框/窗口)為止。

解決了! 我意識到UndoManager的創建與JTextArea擴展對象的focusGained()事件相關聯。 因此,當我通過menuItem選擇操作時,我失去了焦點,UndoManager被破壞了。

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

(...)

不管怎么說,還是要謝謝你!!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM