2016-12-01 9 views
0

私はちょうどjavaのプログラミングに近づいています....私は小さなテキストエディタ(Windowsのメモ帳のクローン...)を作成したいと思います。Javaでの取り消し可能なテキストエリア

私は、アンドゥ& REDOアクションを実装している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()私がこのメニュー項目からの操作を使用するために追加しました...

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

何か提案がありますか? 私の悪い英語のために申し訳ありません...

ありがとう! UndoManagerが破棄され、そこで、

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

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

メニューをクリック

は、テキスト領域が一時的にフォーカスを失った:

+1

==の代わりにメニュー項目を比較するためにequalsを使用してみてください。 – duffymo

+1

いいえ:彼はさらに進んでボタンごとに1つのアクションリスナーを使用する必要があります。それとももっと良いことです:アクションを使用します。 –

+0

"actionPerformed"関数の内部?私は信じていない...動作するメニュー項目に関連する別の14のアクションがあります.... –

答えて

2

問題は、コードが追加とのfocusGainedとのfocusLostイベント時UndoManagerを削除する可能性があります新しいインスタンスが作成されます。新しいインスタンスは、元に戻すことのできる編集イベントを知らないため、取り消しとやり直しは機能しません。

UndoManagerを一度作成し、GUIが配置されるまで(つまりダイアログ/ウィンドウが閉じられるまで)文書に添付したままにすることをお勧めします。

+1

はい!私もそれを実現!どうもありがとうございます!!!! –

1

解決済み! UndoManagerの作成が、私のJTextArea拡張オブジェクトのfocusGained()イベントにリンクされていることに気付きました。だから、私がmenuItemでアクションを選択すると、フォーカスが失われ、UndoManagerが破棄されました。

私は(...)

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

...とにかく

感謝をプライベートからパブリックにメソッドcreateUndoManangerを変更して、クラスの外に呼び出されます!

関連する問題