2016-12-01 2 views
0

저는 자바 프로그래밍에 접근 중입니다 ... 저는 작은 텍스트 편집기 (Windows 메모장 복제본 ...)를 만들고 싶습니다.Java에서 실행 취소 가능한 텍스트 영역

실행 취소 & 다시 실행 작업을 구현하는 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 + 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(); 
} 
} 

제안 사항이 있으십니까? 나쁜 영어로 죄송합니다 ...

감사합니다! 를 UndoManager가 삭제됩니다 그러자,

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

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

당신이 메뉴를 클릭

는, 텍스트 영역이 일시적으로 포커스를 잃었을 :

+1

equals를 사용하여 == 대신 메뉴 항목을 비교해보십시오. – duffymo

+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을 변경하고, 클래스 외부 호출!

관련 문제