Wednesday, 15 August 2012

java - JTextArea setText() & UndoManager -



java - JTextArea setText() & UndoManager -

i'm using undomanager capture changes in jtextarea.

the method settext() deletes , pastes text. when undo firstly see empty area , show text had before.

how reproduce:

run next code click settext() button press ctrl+z undo (you'll see empty textarea!) press ctrl+z undo (you'll see actual previous text)

i want skip 3).

import javax.swing.abstractaction; import javax.swing.jframe; import javax.swing.jtextarea; import javax.swing.keystroke; import javax.swing.event.undoableeditevent; import javax.swing.event.undoableeditlistener; import javax.swing.text.document; import javax.swing.undo.cannotredoexception; import javax.swing.undo.cannotundoexception; import javax.swing.undo.undomanager; import java.awt.event.actionevent; import javax.swing.jbutton; import java.awt.event.actionlistener; @suppresswarnings("serial") public class jtextcomponentsettextundoevent extends jframe { jtextarea area = new jtextarea(); public jtextcomponentsettextundoevent() { setsize(300, 300); setdefaultcloseoperation(exit_on_close); getcontentpane().setlayout(null); area.settext("test"); area.setbounds(0, 96, 146, 165); getcontentpane().add(area); jbutton btnsettext = new jbutton("settext()"); btnsettext.addactionlistener(new actionlistener() { public void actionperformed(actionevent arg0) { area.settext("stackoverflow.com"); } }); btnsettext.setbounds(0, 28, 200, 50); getcontentpane().add(btnsettext); final undomanager undomanager = new undomanager(); document doc = area.getdocument(); doc.addundoableeditlistener(new undoableeditlistener() { public void undoableedithappened(undoableeditevent evt) { undomanager.addedit(evt.getedit()); } }); area.getactionmap().put("undo", new abstractaction("undo") { public void actionperformed(actionevent evt) { seek { if (undomanager.canundo()) { undomanager.undo(); } } grab (cannotundoexception e) { } } }); area.getinputmap().put(keystroke.getkeystroke("control z"), "undo"); area.getactionmap().put("redo", new abstractaction("redo") { public void actionperformed(actionevent evt) { seek { if (undomanager.canredo()) { undomanager.redo(); } } grab (cannotredoexception e) { } } }); area.getinputmap().put(keystroke.getkeystroke("control y"), "redo"); } public static void main(string[] args) { new jtextcomponentsettextundoevent().setvisible(true); } }

you can seek this:

//works fine me on windows 7 x64 using jdk 1.7.0_60: import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import javax.swing.undo.*; public final class undomanagertest { private final jtextfield textfield0 = new jtextfield("default"); private final jtextfield textfield1 = new jtextfield(); private final undomanager undomanager0 = new undomanager(); private final undomanager undomanager1 = new undomanager(); public jcomponent makeui() { textfield1.setdocument(new customundoplaindocument()); textfield1.settext("aaaaaaaaaaaaaaaaaaaaa"); textfield0.getdocument().addundoableeditlistener(undomanager0); textfield1.getdocument().addundoableeditlistener(undomanager1); jpanel p = new jpanel(); p.add(new jbutton(new abstractaction("undo") { @override public void actionperformed(actionevent e) { if (undomanager0.canundo()) { undomanager0.undo(); } if (undomanager1.canundo()) { undomanager1.undo(); } } })); p.add(new jbutton(new abstractaction("redo") { @override public void actionperformed(actionevent e) { if (undomanager0.canredo()) { undomanager0.redo(); } if (undomanager1.canredo()) { undomanager1.redo(); } } })); p.add(new jbutton(new abstractaction("settext(new date())") { @override public void actionperformed(actionevent e) { string str = new date().tostring(); textfield0.settext(str); textfield1.settext(str); } })); box box = box.createverticalbox(); box.setborder(borderfactory.createemptyborder(5, 5, 5, 5)); box.add(makepanel("default", textfield0)); box.add(box.createverticalstrut(5)); box.add(makepanel("replace ignoring undo", textfield1)); jpanel pp = new jpanel(new borderlayout()); pp.add(box, borderlayout.north); pp.add(p, borderlayout.south); homecoming pp; } private static jpanel makepanel(string title, jcomponent c) { jpanel p = new jpanel(new borderlayout()); p.setborder(borderfactory.createtitledborder(title)); p.add(c); homecoming p; } public static void main(string[] args) { eventqueue.invokelater(new runnable() { @override public void run() { createandshowgui(); } }); } public static void createandshowgui() { jframe f = new jframe(); f.setdefaultcloseoperation(windowconstants.exit_on_close); f.getcontentpane().add(new undomanagertest().makeui()); f.setsize(320, 240); f.setlocationrelativeto(null); f.setvisible(true); } } 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) { system.out.println("insert"); super.replace(offset, length, text, attrs); } else { system.out.println("replace"); compoundedit = new compoundedit(); super.fireundoableeditupdate(new undoableeditevent(this, compoundedit)); super.replace(offset, length, text, attrs); compoundedit.end(); compoundedit = null; } } }

java swing jtextarea undo-redo

No comments:

Post a Comment