5 Replies Latest reply on May 23, 2002 7:17 PM by 807582

    Undo two or more actions at once

    807582
      I have seen this question asked before without an answer and I have asked it with the title " HTMLDocument setInnerHTML or setOuterHTML and Undo", but without an answer as well.

      I a have a few actions that use the setInnerHTML() and setOuterHTML() which actually perform an insert and then a remove element. This issue is not specific to the HTMLDocment, but to the use of an UndoManager.

      How do I manipulate the data to return to its state prior to the end result of an action that is made up of more than one undoable edits? Basically, how would I group two, or possibly more, UndoableEdits as one UndoableEdit?

      Although I am continueing to work on other aspects of my code, I am eventually going to be held up with this issue if I don't find a resolution.
        • 1. Re: Undo two or more actions at once
          807582
          In your undo method, just call undo twice, or whatever you need.
          • 2. Re: Undo two or more actions at once
            807582
            Actually, not all of the actions use multiple undoable edits, i.e. bold, italic, pasting, cutting, etc. Perhaps there is a way to flag undoable edits as part of a sequence. Has anyone solve this issue before?

            Thank you inadvace for your assistance.
            • 3. Re: Undo two or more actions at once
              807582
              UndoableEdit.addEdit(anEdit) does what you want
              • 4. Re: Undo two or more actions at once
                camickr
                Here is a sample program that shows the concept of using CompoundEdits. It does not address how to programmatically start/stop a compound edit. Hope its of some help.

                import java.awt.*;
                import java.awt.event.*;
                import javax.swing.*;
                import javax.swing.text.*;
                import javax.swing.event.*;
                import javax.swing.undo.*;

                public class TestCompoundEdit extends JFrame
                {
                     private MyUndoableEditListener myUndoableEditListener;
                     private UndoManager undoManager;
                     private CompoundEdit compoundEdit;
                     private boolean compounding;
                     private JTextPane textPane;

                public TestCompoundEdit()
                {
                          undoManager = new UndoManager();
                          myUndoableEditListener = new MyUndoableEditListener();

                JPanel panel = new JPanel();
                panel.setLayout( new BorderLayout() );
                     setContentPane( panel );

                          textPane = new JTextPane();
                          textPane.setPreferredSize( new Dimension(200, 200) );
                          textPane.getDocument().addUndoableEditListener( myUndoableEditListener );
                          panel.add( textPane, BorderLayout.CENTER );

                          JPanel buttons = new JPanel();
                          panel.add(buttons, BorderLayout.SOUTH);

                          final JButton start = new JButton( "Start Compound Edit" );
                          start.addActionListener( new ActionListener()
                          {
                               public void actionPerformed(ActionEvent e)
                               {

                                    if (isCompoundEdit())
                                    {
                                    compoundEdit.end();
                                    undoManager.addEdit( compoundEdit );
                                    setCompoundEdit( false );
                                    start.setText( "Start Compound Edit" );
                               }
                                    else
                                    {
                                         compoundEdit = new CompoundEdit();
                                         setCompoundEdit( true );
                                    start.setText( "Stop Compound Edit" );
                                    }

                                    textPane.requestFocus();
                               }
                          });
                          buttons.add( start );

                          JButton undo = new JButton( "Undo" );
                          undo.addActionListener( new ActionListener()
                          {
                               public void actionPerformed(ActionEvent e)
                               {
                               try
                               {
                                    undoManager.undo();
                                         textPane.requestFocus();
                               }
                               catch (CannotUndoException ex)
                               {
                                    System.out.println("Unable to undo: " + ex);
                               }
                               }
                          });
                          buttons.add( undo );

                          JButton redo = new JButton( "Redo" );
                          redo.addActionListener( new ActionListener()
                          {
                               public void actionPerformed(ActionEvent e)
                               {
                               try
                               {
                                    undoManager.redo();
                                         textPane.requestFocus();
                               }
                               catch (CannotRedoException ex)
                               {
                                    System.out.println("Unable to redo: " + ex);
                               }
                               }
                          });
                          buttons.add( redo );
                     }

                     public void setCompoundEdit(boolean value)
                     {
                          compounding = value;
                     }

                     public boolean isCompoundEdit()
                     {
                          return compounding;
                     }

                     class MyUndoableEditListener implements UndoableEditListener
                     {
                          public void undoableEditHappened(UndoableEditEvent e)
                          {
                               if (isCompoundEdit())
                                    compoundEdit.addEdit(e.getEdit());
                               else
                               {
                                    undoManager.addEdit(e.getEdit());
                               }
                          }
                     }
                public static void main(String[] args)
                {
                TestCompoundEdit frame = new TestCompoundEdit();
                frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
                frame.pack();
                frame.setVisible(true);
                }
                }
                • 5. Re: Undo two or more actions at once
                  807582
                  Thanks for the lead. I researched it a little and coded the below. It works so far. Thanks for the help.
                  public class ExtendedHTMLDocument extends HTMLDocument {
                  
                       private boolean undoableSequence = false;
                       private javax.swing.undo.CompoundEdit compoundEdit  = null;
                  
                       protected boolean isUndoableSequence() {
                            return undoableSequence;
                       }
                       protected void startUndoableSequence() {
                            endUndoableSequence();
                            undoableSequence = true;
                       }
                       protected void endUndoableSequence() {
                            if (compoundEdit != null && compoundEdit.isInProgress()) {
                                 compoundEdit.end();
                            }
                            compoundEdit = null;
                            undoableSequence = false;
                       }
                       protected javax.swing.undo.CompoundEdit getUndoableSequence() {
                            if (compoundEdit == null) {
                                 compoundEdit = new javax.swing.undo.CompoundEdit();
                                 super.fireUndoableEditUpdate(new UndoableEditEvent(this, compoundEdit));
                            }
                            return compoundEdit;
                       }
                       protected void fireUndoableEditUpdate(UndoableEditEvent _event) {
                            if (isUndoableSequence()) {
                                 getUndoableSequence().addEdit(_event.getEdit());
                            }
                            else {
                                 super.fireUndoableEditUpdate(_event);
                            }
                       }
                       public void setInnerHTML(Element _element, String _htmlText) throws BadLocationException, java.io.IOException {
                            startUndoableSequence();
                            super.setInnerHTML(_element, _htmlText);
                            endUndoableSequence();
                       }
                       public void setOuterHTML(Element _element, String _htmlText) throws BadLocationException, java.io.IOException {
                            startUndoableSequence();
                            super.setOuterHTML(_element, _htmlText);
                            endUndoableSequence();
                       }
                  }