Swing/ReplaceUndoableEdit のバックアップの現在との差分(No.13)
-
category: swing
folder: ReplaceUndoableEdit
title: UndoManagerを使用した文字列選択ペーストの動作を変更する
tags: [JTextField, UndoManager, PlainDocument, JTextComponent, CompoundEdit, DocumentFilter, UndoableEdit]
author: aterai
pubdate: 2012-10-15T14:31:20+09:00
description: JTextFieldなどにUndoManagerを設定し、文字列を選択してペーストした後のUndoの動作を変更します。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2014/06/merge-replaceeditremove-and.html lang: en
概要
概要
JTextField
などにUndoManager
を設定し、文字列を選択してペーストした後のUndo
の動作を変更します。
Screenshot
![Swing/ReplaceUndoableEdit screenshot](https://ateraimemo.com/swing/replaceundoableedit/screenshot.png)
Advertisement
サンプルコード
サンプルコード
class CustomUndoPlainDocument extends PlainDocument {
private CompoundEdit compoundEdit;
@Override protected void fireUndoableEditUpdate(UndoableEditEvent e) {
if (compoundEdit == null) {
super.fireUndoableEditUpdate(e);
} else {
compoundEdit.addEdit(e.getEdit());
}
}
#spanadd
#spanend
@Override public void replace(
int offset, int length, String text, AttributeSet attrs)
throws BadLocationException {
if (length == 0) { //insert
if (length == 0) { // insert
System.out.println("insert");
super.replace(offset, length, text, attrs);
} else { //replace
} else { // replace
System.out.println("replace");
compoundEdit = new CompoundEdit();
super.fireUndoableEditUpdate(new UndoableEditEvent(this, compoundEdit));
super.replace(offset, length, text, attrs);
compoundEdit.end();
compoundEdit = null;
}
}
}
View in GitHub: Java, Kotlin解説
解説
- 上:
Default
-
JTextComponent#setText(String)
や、文字列を選択してペーストした場合、Document#replace(...)
で実行されるDocument#remove(...)
とDocument#insertString(...)
が別々にUndoManager
に登録される仕様?なので、二回Undo
しないとペースト前の状態に戻らない -
JTextComponent#setText(String)
メソッドや文字列を選択してペーストした場合、Document#replace(...)
で実行されるDocument#remove(...)
とDocument#insertString(...)
が別々にUndoManager
に登録される仕様なので2
回Undo
しないとペースト前の状態まで戻らない
-
- 中:
Document#replace()+AbstractDocument#fireUndoableEditUpdate()
Document#replace(...)
をオーバーライドし、直接UndoManager#undoableEditHappened(...)
を使って取り消し可能な編集を登録setText(...)
での文字列の削除と追加をCompoundEdit
にまとめる-
実際の置換は、removeUndoableEditListener(...)
でUndoManager
を一時的に削除した後に行う(直後にaddUndoableEditListener()
で再登録) -
登録するUndoableEdit
でのUndo
,Redo
時の置換もUndoManager
を一時的に削除して行う -
実際の置換はremoveUndoableEditListener(...)
でUndoManager
を一時的に削除した後に行う(直後にaddUndoableEditListener()
で再登録) -
登録するUndoableEdit
でのUndo
、Redo
時の置換もUndoManager
を一時的に削除して行う - メモ: このサンプルでは選択状態を復元していない
- 下:
DocumentFilter#replace()+UndoableEditListener#undoableEditHappened()
DocumentFilter#replace(...)
をオーバーライドし、文字列の置換で発生する削除と追加のUndoableEdit
を別途用意したCompoundEdit
にまとめてからUndoManager#addEdit(...)
で追加
class DocumentFilterUndoManager extends UndoManager {
private CompoundEdit compoundEdit;
private final transient DocumentFilter undoFilter = new DocumentFilter() {
@Override public void replace(
DocumentFilter.FilterBypass fb, int offset, int length,
String text, AttributeSet attrs) throws BadLocationException {
if (length == 0) {
fb.insertString(offset, text, attrs);
} else {
compoundEdit = new CompoundEdit();
fb.replace(offset, length, text, attrs);
compoundEdit.end();
addEdit(compoundEdit);
compoundEdit = null;
}
}
};
#spanadd
#spanend
public DocumentFilter getDocumentFilter() {
return undoFilter;
}
#spanadd
#spanend
@Override public void undoableEditHappened(UndoableEditEvent e) {
if (compoundEdit == null) {
addEdit(e.getEdit());
} else {
compoundEdit.addEdit(e.getEdit());
}
Optional.ofNullable(compoundEdit).orElse(this).addEdit(e.getEdit());
}
}
参考リンク
参考リンク
- Undo two or more actions at once | Oracle Community
- Undo manager : Undo Redo « Swing JFC « Java
- Compound Undo Manager ≪ Java Tips Weblog
- Compound Undo Manager ≪ Java Tips Weblog
- Merging UndoableEdits in one to be undone all together in JEditorPane.
- java - JTextArea setText() & UndoManager - Stack Overflow
- java - Undo in JTextField and setText - Stack Overflow
- Java Swing「UndoManager」メモ(Hishidama's Swing-UndoManager Memo)
- java - JTextArea setText() & UndoManager - Stack Overflow
- java - Undo in JTextField and setText - Stack Overflow
- Java Swing「UndoManager」メモ(Hishidama's Swing-UndoManager Memo)
- Java Swingで複数のJTextFieldに対してUndo、Redoを行う(その2)-解決編 kyoはパソコンMaster or Slave?/ウェブリブログ
- バカが征く on Rails 2010年03月16日()
- UndoManagerでJTextFieldのUndo、Redoを行う