Hi to everyone!!!
I need your advice for my problem!!
when I cliked new in the file to create a new JTextPane the undo redo button will multiply and if I have so many JTextPane then I have many undo redo in my toolbar
here is my code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import java.util.*;
import javax.swing.undo.*;
public class URTest extends JFrame {
JToolBar toolBar = new JToolBar();
JButton undo;
JButton redo = new JButton("Redo");
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
JMenuItem item = new JMenuItem("New");
JMenuItem item2 = new JMenuItem("Close");
JTabbedPane tabbedPane = new JTabbedPane();
JTextPane pane;
public URTest() {
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
create();
}
});
item2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
removeCreate();
}
});
menu.add(item);
menu.add(item2);
menuBar.add(menu);
this.add(toolBar,BorderLayout.NORTH);
this.add(tabbedPane);
this.setJMenuBar(menuBar);
}
void create() {
undo = new JButton("Undo");
redo = new JButton("Redo");
pane = new JTextPane();
EditorKit editorKit = new StyledEditorKit() {
public Document createDefaultDocument() {
return new SyntaxDocument();
}
};
pane.setEditorKit(editorKit);
final CompoundUndoManager undoManager = new CompoundUndoManager( pane );
undo.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
undoManager.undo();
pane.requestFocus();
}
catch (CannotUndoException ex)
{
System.out.println("Unable to undo: " + ex);
}
}
});
redo.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
undoManager.redo();
pane.requestFocus();
}
catch (CannotRedoException ex)
{
System.out.println("Unable to redo: " + ex);
}
}
});
toolBar.add(undo);
toolBar.add(redo);
tabbedPane.addTab("Tab",pane);
}
void removeCreate() {
tabbedPane.remove(tabbedPane.getSelectedIndex());
}
public static void main(String[] args) {
URTest frame = new URTest();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize(400,400);
frame.setVisible(true);
}
}
class CompoundUndoManager extends UndoManager
implements UndoableEditListener, DocumentListener
{
public CompoundEdit compoundEdit;
private JTextComponent editor;
// These fields are used to help determine whether the edit is an
// incremental edit. For each character added the offset and length
// should increase by 1 or decrease by 1 for each character removed.
private int lastOffset;
private int lastLength;
public CompoundUndoManager(JTextComponent editor)
{
this.editor = editor;
editor.getDocument().addUndoableEditListener( this );
}
/*
** Add a DocumentLister before the undo is done so we can position
** the Caret correctly as each edit is undone.
*/
public void undo()
{
editor.getDocument().addDocumentListener( this );
super.undo();
editor.getDocument().removeDocumentListener( this );
}
/*
** Add a DocumentLister before the redo is done so we can position
** the Caret correctly as each edit is redone.
*/
public void redo()
{
editor.getDocument().addDocumentListener( this );
super.redo();
editor.getDocument().removeDocumentListener( this );
}
/*
** Whenever an UndoableEdit happens the edit will either be absorbed
** by the current compound edit or a new compound edit will be started
*/
public void undoableEditHappened(UndoableEditEvent e)
{
// Start a new compound edit
if (compoundEdit == null)
{
compoundEdit = startCompoundEdit( e.getEdit() );
lastLength = editor.getDocument().getLength();
return;
}
// Check for an attribute change
AbstractDocument.DefaultDocumentEvent event =
(AbstractDocument.DefaultDocumentEvent)e.getEdit();
if (event.getType().equals(DocumentEvent.EventType.CHANGE))
{
compoundEdit.addEdit( e.getEdit() );
return;
}
// Check for an incremental edit or backspace.
// The change in Caret position and Document length should be either
// 1 or -1 .
int offsetChange = editor.getCaretPosition() - lastOffset;
int lengthChange = editor.getDocument().getLength() - lastLength;
if (Math.abs(offsetChange) == 1
&& Math.abs(lengthChange) == 1)
{
compoundEdit.addEdit( e.getEdit() );
lastOffset = editor.getCaretPosition();
lastLength = editor.getDocument().getLength();
return;
}
// Not incremental edit, end previous edit and start a new one
compoundEdit.end();
compoundEdit = startCompoundEdit( e.getEdit() );
}
/*
** Each CompoundEdit will store a group of related incremental edits
** (ie. each character typed or backspaced is an incremental edit)
*/
private CompoundEdit startCompoundEdit(UndoableEdit anEdit)
{
// Track Caret and Document information of this compound edit
lastOffset = editor.getCaretPosition();
lastLength = editor.getDocument().getLength();
// The compound edit is used to store incremental edits
compoundEdit = new MyCompoundEdit();
compoundEdit.addEdit( anEdit );
// The compound edit is added to the UndoManager. All incremental
// edits stored in the compound edit will be undone/redone at once
addEdit( compoundEdit );
return compoundEdit;
}
// Implement DocumentListener
//
// Updates to the Document as a result of Undo/Redo will cause the
// Caret to be repositioned
public void insertUpdate(final DocumentEvent e)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
int offset = e.getOffset() + e.getLength();
offset = Math.min(offset, editor.getDocument().getLength());
editor.setCaretPosition( offset );
}
});
}
public void removeUpdate(DocumentEvent e)
{
editor.setCaretPosition(e.getOffset());
}
public void changedUpdate(DocumentEvent e) {}
class MyCompoundEdit extends CompoundEdit
{
public boolean isInProgress()
{
// in order for the canUndo() and canRedo() methods to work
// assume that the compound edit is never in progress
return false;
}
public void undo() throws CannotUndoException
{
// End the edit so future edits don't get absorbed by this edit
if (compoundEdit != null)
compoundEdit.end();
super.undo();
// Always start a new compound edit after an undo
compoundEdit = null;
}
}
}