Swing/ReplaceUndoableEdit のバックアップソース(No.20)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- バックアップ を表示
- Swing/ReplaceUndoableEdit へ行く。
- 1 (2012-10-15 (月) 14:31:20)
- 2 (2012-10-15 (月) 16:57:03)
- 3 (2012-10-15 (月) 19:54:03)
- 4 (2012-10-15 (月) 21:39:49)
- 5 (2012-10-17 (水) 17:08:44)
- 6 (2012-11-20 (火) 21:25:01)
- 7 (2012-12-05 (水) 18:27:44)
- 8 (2012-12-07 (金) 16:32:57)
- 9 (2014-06-27 (金) 20:06:06)
- 10 (2014-06-29 (日) 01:30:53)
- 11 (2014-11-06 (木) 01:08:59)
- 12 (2014-11-06 (木) 04:17:22)
- 13 (2014-11-19 (水) 20:14:21)
- 14 (2014-11-21 (金) 18:11:05)
- 15 (2015-12-18 (金) 16:26:34)
- 16 (2016-09-23 (金) 02:21:02)
- 17 (2016-09-27 (火) 01:10:08)
- 18 (2017-04-07 (金) 13:51:51)
- 19 (2017-11-02 (木) 15:32:16)
- 20 (2017-11-04 (土) 00:09:26)
- 21 (2018-02-24 (土) 19:51:30)
- 22 (2019-04-19 (金) 13:43:27)
- 23 (2019-05-30 (木) 18:34:13)
- 24 (2021-02-19 (金) 04:20:29)
--- 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: https://lh5.googleusercontent.com/-GEc9R-QZvos/UKt2czK61tI/AAAAAAAABXk/vqH8TKxkqCM/s800/ReplaceUndoableEdit.png hreflang: href: http://java-swing-tips.blogspot.com/2014/06/merge-replaceeditremove-and.html lang: en --- * 概要 [#summary] `JTextField`などに`UndoManager`を設定し、文字列を選択してペーストした後の`Undo`の動作を変更します。 #download(https://lh5.googleusercontent.com/-GEc9R-QZvos/UKt2czK61tI/AAAAAAAABXk/vqH8TKxkqCM/s800/ReplaceUndoableEdit.png) * サンプルコード [#sourcecode] #code(link){{ class CustomUndoPlainDocument extends PlainDocument { private CompoundEdit compoundEdit; @Override protected void fireUndoableEditUpdate(UndoableEditEvent e) { if (compoundEdit == null) { super.fireUndoableEditUpdate(e); } else { compoundEdit.addEdit(e.getEdit()); } } @Override public void replace( int offset, int length, String text, AttributeSet attrs) throws BadLocationException { if (length == 0) { //insert System.out.println("insert"); super.replace(offset, length, text, attrs); } 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; } } } }} * 解説 [#explanation] - 上: `Default` -- `JTextComponent#setText(String)`や、文字列を選択してペーストした場合、`Document#replace(...)`で実行される`Document#remove(...)`と`Document#insertString(...)`が別々に`UndoManager`に登録される仕様なので、二回`Undo`しないとペースト前の状態まで戻らない - 中: `Document#replace()+AbstractDocument#fireUndoableEditUpdate()` -- `Document#replace(...)`をオーバーライドし、%%直接`UndoManager#undoableEditHappened(...)`を使って取り消し可能な編集を登録%% `setText(...)`での文字列の削除と追加を`CompoundEdit`にまとめる -- %%実際の置換は、`removeUndoableEditListener(...)`で`UndoManager`を一時的に削除した後に行う(直後に`addUndoableEditListener()`で再登録)%% -- %%登録する`UndoableEdit`での`Undo`, `Redo`時の置換も`UndoManager`を一時的に削除して行う%% -- メモ: このサンプルでは選択状態を復元していない - 下: `DocumentFilter#replace()+UndoableEditListener#undoableEditHappened()` -- `DocumentFilter#replace(...)`をオーバーライドし、文字列の置換で発生する削除と追加の`UndoableEdit`を別途用意した`CompoundEdit`にまとめてから`UndoManager#addEdit(...)`で追加 #code{{ 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; } } }; public DocumentFilter getDocumentFilter() { return undoFilter; } @Override public void undoableEditHappened(UndoableEditEvent e) { Optional.ofNullable(compoundEdit).orElse(this).addEdit(e.getEdit()); } } }} * 参考リンク [#reference] - [https://community.oracle.com/thread/1509622 Undo two or more actions at once | Oracle Community] - [http://www.java2s.com/Code/Java/Swing-JFC/Undomanager.htm Undo manager : Undo Redo « Swing JFC « Java] - [https://tips4java.wordpress.com/2008/10/27/compound-undo-manager/ Compound Undo Manager ≪ Java Tips Weblog] - [http://java-sl.com/tip_merge_undo_edits.html Merging UndoableEdits in one to be undone all together in JEditorPane.] - [https://stackoverflow.com/questions/24433089/jtextarea-settext-undomanager java - JTextArea setText() & UndoManager - Stack Overflow] - [https://stackoverflow.com/questions/12844520/undo-in-jtextfield-and-settext java - Undo in JTextField and setText - Stack Overflow] - [http://www.ne.jp/asahi/hishidama/home/tech/java/swing/UndoManager.html Java Swing「UndoManager」メモ(Hishidama's Swing-UndoManager Memo)] - [http://kyopc.at.webry.info/201007/article_1.html Java Swingで複数のJTextFieldに対してUndo、Redoを行う(その2)-解決編 kyoはパソコンMaster or Slave?/ウェブリブログ] - [http://bakagaiku.hsbt.org/entry/20100316 バカが征く on Rails 2010年03月16日()] - [[UndoManagerでJTextFieldのUndo、Redoを行う>Swing/UndoManager]] * コメント [#comment] #comment #comment