JEditorPane插入很多字符和撤销 恢复操作, 下面是代码, NewFrame类中 调用 UndoWrapper类
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt. event .ActionEvent;
import java.awt. event .ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.WindowConstants;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import work.UndoWrapper;
public class NewJFrame extends javax.swing.JFrame implements ActionListener ... {
private JPanel jp1;
private JTextPane jep;
private JScrollPane jsp;
private JButton font;
private JButton redo;
private JButton cancel;
private JButton replace;
private static ArrayList<Document> beifenDoc = new ArrayList<Document>();
private static int cancelIndex = 0;
private static int docIndex = 0;
private static Document yyy;
private static UndoWrapper undo;
/**//**
* Auto-generated main method to display this JFrame
*/
public static void main(String[] args) ...{
NewJFrame inst = new NewJFrame();
inst.setVisible(true);
}
public NewJFrame() ...{
super();
initGUI();
}
private void initGUI() ...{
try ...{
BorderLayout thisLayout = new BorderLayout();
getContentPane().setLayout(thisLayout);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
...{
jp1 = new JPanel();
getContentPane().add(jp1, BorderLayout.NORTH);
...{
font = new JButton();
font.addActionListener(this);
jp1.add(font);
font.setText("font");
}
...{
redo = new JButton();
jp1.add(redo);
redo.addActionListener(this);
redo.setText("redo");
}
...{
cancel = new JButton();
jp1.add(cancel);
cancel.addActionListener(this);
cancel.setText("cancel");
}
...{
replace = new JButton();
jp1.add(replace);
replace.addActionListener(this);
replace.setText("replace");
}
}
...{
jsp = new JScrollPane();
getContentPane().add(jsp, BorderLayout.CENTER);
...{
jep = new JTextPane();
jep.setText(openFile("g:/spring_mass.adm.txt"));
jep.setEditable(false);
yyy = jep.getDocument();
undo = new UndoWrapper(jep);
//(Sundo.undoManager).undo();
beifenDoc.add(jep.getDocument());
jsp.setViewportView(jep);
// jep.setStyledDocument(new DefaultStyledDocument());
}
}
pack();
setSize(400, 300);
} catch (Exception e) ...{
e.printStackTrace();
}
}
/**//**
*
* @param editor
* 因为 在 initGUI()中 已经将 本程序中的JEditorPane与UndoWrapper关联,即new UndoWrapper(jep);
* 所以,采用现成的实现 JEditorPane 撤销 恢复功能 的类 UndoWrapper,调用其中的undoManager属性,
* 进行响应的操作。
*
*/
public static void cancel(JEditorPane editor) ...{
try...{
undo.undoManager.undo();
}catch(CannotUndoException e)...{
System.out.println("无可撤销");
}
}
public static void redo(JEditorPane editor) ...{
try...{
undo.undoManager.redo();
}catch(CannotRedoException e)...{
System.out.println("无可恢复");
}
}
private String openFile(String filePath) ...{
File f = new File(filePath);
String ee = new String();
System.out.println("Opening file: " + filePath);
try ...{
InputStream is = new FileInputStream(f);
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String line; // 用来保存每行读取的内容
line = reader.readLine(); // 读取第一行
while (line != null) ...{ // 如果 line 为空说明读完了
buffer.append(line); // 将读到的内容添加到 buffer 中
buffer.append(" "); // 添加换行符
line = reader.readLine(); // 读取下一行
}
// System.out.print(buffer.toString());
ee = buffer.toString();
}
catch (FileNotFoundException e) ...{
e.printStackTrace();
} catch (IOException e) ...{
e.printStackTrace();
}
return ee;
}
public static void replace(JEditorPane editor, String objective) ...{
try ...{
MutableAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setBackground(attr, Color.BLUE);// 理解为,先将颜色改变赋予属性,
Document docs = editor.getDocument();
String fileString = editor.getText();
int size = fileString.length();
String selectedString = editor.getSelectedText();
if (selectedString == null)...{
return;
}
int s0 = fileString.indexOf(selectedString)
+ selectedString.length();
int s1 = fileString.indexOf(",", s0);
int s2 = fileString.indexOf(" ", s0);
int s3 = fileString.indexOf(" ", s0);
int s4 = fileString.indexOf(" ", s0);
if (s1 < 0)
s1 = size;
if (s2 < 0)
s2 = size;
if (s3 < 0)
s3 = size;
if (s4 < 0)
s4 = size;
int endIndex = Math.min(Math.min(Math.min(s1, s2), s3), s4);
if (endIndex > s0) ...{
docs.remove(s0, endIndex - s0);
docs.insertString(s0, objective, attr);
beifenDoc.add(docs);
} else ...{
int enter = fileString.indexOf(" ", s0);
if (enter == s0)
return;
int s00 = s0 + 1;
s1 = fileString.indexOf(",", s00);
s2 = fileString.indexOf(" ", s00);
s3 = fileString.indexOf(" ", s00);
s4 = fileString.indexOf(" ", s00);
if (s1 < 0)
s1 = size;
if (s2 < 0)
s2 = size;
if (s3 < 0)
s3 = size;
if (s4 < 0)
s4 = size;
endIndex = Math.min(Math.min(Math.min(s1, s2), s3), s4);
docs.remove(s00, endIndex - s00);
docs.insertString(s00, objective, attr);
beifenDoc.add(docs);
}
} catch (BadLocationException e) ...{
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent e) ...{
Object obj = e.getSource();
if (obj == cancel) ...{
JEditorPane editor = jep;
cancel(editor);
}
if (obj == redo) ...{
JEditorPane editor = jep;
redo(editor);
}
if (obj == replace) ...{
JEditorPane editor = jep;
replace(editor, "QQ");
}
}
}
import java.awt.Color;
import java.awt. event .ActionEvent;
import java.awt. event .ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.WindowConstants;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import work.UndoWrapper;
public class NewJFrame extends javax.swing.JFrame implements ActionListener ... {
private JPanel jp1;
private JTextPane jep;
private JScrollPane jsp;
private JButton font;
private JButton redo;
private JButton cancel;
private JButton replace;
private static ArrayList<Document> beifenDoc = new ArrayList<Document>();
private static int cancelIndex = 0;
private static int docIndex = 0;
private static Document yyy;
private static UndoWrapper undo;
/**//**
* Auto-generated main method to display this JFrame
*/
public static void main(String[] args) ...{
NewJFrame inst = new NewJFrame();
inst.setVisible(true);
}
public NewJFrame() ...{
super();
initGUI();
}
private void initGUI() ...{
try ...{
BorderLayout thisLayout = new BorderLayout();
getContentPane().setLayout(thisLayout);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
...{
jp1 = new JPanel();
getContentPane().add(jp1, BorderLayout.NORTH);
...{
font = new JButton();
font.addActionListener(this);
jp1.add(font);
font.setText("font");
}
...{
redo = new JButton();
jp1.add(redo);
redo.addActionListener(this);
redo.setText("redo");
}
...{
cancel = new JButton();
jp1.add(cancel);
cancel.addActionListener(this);
cancel.setText("cancel");
}
...{
replace = new JButton();
jp1.add(replace);
replace.addActionListener(this);
replace.setText("replace");
}
}
...{
jsp = new JScrollPane();
getContentPane().add(jsp, BorderLayout.CENTER);
...{
jep = new JTextPane();
jep.setText(openFile("g:/spring_mass.adm.txt"));
jep.setEditable(false);
yyy = jep.getDocument();
undo = new UndoWrapper(jep);
//(Sundo.undoManager).undo();
beifenDoc.add(jep.getDocument());
jsp.setViewportView(jep);
// jep.setStyledDocument(new DefaultStyledDocument());
}
}
pack();
setSize(400, 300);
} catch (Exception e) ...{
e.printStackTrace();
}
}
/**//**
*
* @param editor
* 因为 在 initGUI()中 已经将 本程序中的JEditorPane与UndoWrapper关联,即new UndoWrapper(jep);
* 所以,采用现成的实现 JEditorPane 撤销 恢复功能 的类 UndoWrapper,调用其中的undoManager属性,
* 进行响应的操作。
*
*/
public static void cancel(JEditorPane editor) ...{
try...{
undo.undoManager.undo();
}catch(CannotUndoException e)...{
System.out.println("无可撤销");
}
}
public static void redo(JEditorPane editor) ...{
try...{
undo.undoManager.redo();
}catch(CannotRedoException e)...{
System.out.println("无可恢复");
}
}
private String openFile(String filePath) ...{
File f = new File(filePath);
String ee = new String();
System.out.println("Opening file: " + filePath);
try ...{
InputStream is = new FileInputStream(f);
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String line; // 用来保存每行读取的内容
line = reader.readLine(); // 读取第一行
while (line != null) ...{ // 如果 line 为空说明读完了
buffer.append(line); // 将读到的内容添加到 buffer 中
buffer.append(" "); // 添加换行符
line = reader.readLine(); // 读取下一行
}
// System.out.print(buffer.toString());
ee = buffer.toString();
}
catch (FileNotFoundException e) ...{
e.printStackTrace();
} catch (IOException e) ...{
e.printStackTrace();
}
return ee;
}
public static void replace(JEditorPane editor, String objective) ...{
try ...{
MutableAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setBackground(attr, Color.BLUE);// 理解为,先将颜色改变赋予属性,
Document docs = editor.getDocument();
String fileString = editor.getText();
int size = fileString.length();
String selectedString = editor.getSelectedText();
if (selectedString == null)...{
return;
}
int s0 = fileString.indexOf(selectedString)
+ selectedString.length();
int s1 = fileString.indexOf(",", s0);
int s2 = fileString.indexOf(" ", s0);
int s3 = fileString.indexOf(" ", s0);
int s4 = fileString.indexOf(" ", s0);
if (s1 < 0)
s1 = size;
if (s2 < 0)
s2 = size;
if (s3 < 0)
s3 = size;
if (s4 < 0)
s4 = size;
int endIndex = Math.min(Math.min(Math.min(s1, s2), s3), s4);
if (endIndex > s0) ...{
docs.remove(s0, endIndex - s0);
docs.insertString(s0, objective, attr);
beifenDoc.add(docs);
} else ...{
int enter = fileString.indexOf(" ", s0);
if (enter == s0)
return;
int s00 = s0 + 1;
s1 = fileString.indexOf(",", s00);
s2 = fileString.indexOf(" ", s00);
s3 = fileString.indexOf(" ", s00);
s4 = fileString.indexOf(" ", s00);
if (s1 < 0)
s1 = size;
if (s2 < 0)
s2 = size;
if (s3 < 0)
s3 = size;
if (s4 < 0)
s4 = size;
endIndex = Math.min(Math.min(Math.min(s1, s2), s3), s4);
docs.remove(s00, endIndex - s00);
docs.insertString(s00, objective, attr);
beifenDoc.add(docs);
}
} catch (BadLocationException e) ...{
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent e) ...{
Object obj = e.getSource();
if (obj == cancel) ...{
JEditorPane editor = jep;
cancel(editor);
}
if (obj == redo) ...{
JEditorPane editor = jep;
redo(editor);
}
if (obj == replace) ...{
JEditorPane editor = jep;
replace(editor, "QQ");
}
}
}
使用的时候,只需要将你创建的
JEditorPane
作为对象传入
UndoWrapper
中即可。使用方式如下
new UndoWrapper(editorPane);
OK
这样你的编辑器就具有了
Undo Redo
功能,而且是次数不收限制的。
我在使用的时候,除了
UndoWrapper undo = new UndoWrapper(editorPane); 这一步必不可少之外,在按钮的相应程序段, actionPerformend()中
undo.undoManager.undo(),这样才实现了像记事本,word等的撤销功能
package work;
import java.awt. event .ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JEditorPane;
import javax.swing.KeyStroke;
import javax.swing. event .UndoableEditEvent;
import javax.swing. event .UndoableEditListener;
import javax.swing.text.JTextComponent;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
/**/ /**
* UndoWrapper is responsible for adding undo and redo support to text
* components.
*
* @author Antonio Vieiro (antonio@antonioshome.net), $Author: $
* @version $Revision: $
*/
public class UndoWrapper implements UndoableEditListener ... {
public UndoManager undoManager;
private UndoAction undoAction;
private RedoAction redoAction;
private JEditorPane textComponent;
/**//**
* Creates a new instance of UndoWrapper
*/
public UndoWrapper(JEditorPane aComponent) ...{
textComponent = aComponent;
undoManager = new UndoManager();
undoAction = new UndoAction();
redoAction = new RedoAction();
textComponent.getDocument().addUndoableEditListener(this);
textComponent.getInputMap()
.put((KeyStroke) undoAction.getValue(Action.ACCELERATOR_KEY),
"undo");
textComponent.getInputMap()
.put((KeyStroke) redoAction.getValue(Action.ACCELERATOR_KEY),
"redo");
textComponent.getActionMap().put("undo", undoAction);
textComponent.getActionMap().put("redo", redoAction);
}
public void undoableEditHappened(UndoableEditEvent e) ...{
undoManager.addEdit(e.getEdit());
undoAction.updateUndoState();
redoAction.updateRedoState();
}
/**//**
* UndoAction is the Action responsible for handling the undo operation.
*/
class UndoAction extends AbstractAction ...{
public UndoAction() ...{
super("Cannot undo"); // TODO: I18N
setEnabled(false);
putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl Z"));
}
public void actionPerformed(ActionEvent e) ...{
try ...{
undoManager.undo();
} catch (CannotUndoException cue) ...{
// TODO: Use logging?
cue.printStackTrace(System.err);
}
updateUndoState();
redoAction.updateRedoState();
}
void updateUndoState() ...{
if (undoManager.canUndo()) ...{
setEnabled(true);
putValue(Action.NAME, "Undo"); // TODO I18N
} else ...{
setEnabled(false);
putValue(Action.NAME, "Cannot undo"); // TODO I18N
}
}
}
/**//**
* RedoAction is the Action responsible for handling the redo operation.
*/
class RedoAction extends AbstractAction ...{
public RedoAction() ...{
super("Cannot redo"); // TODO I18N
setEnabled(false);
putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl Y"));
}
public void actionPerformed(ActionEvent e) ...{
try ...{
undoManager.redo();
} catch (CannotRedoException cre) ...{
// TODO: Use logging?
cre.printStackTrace(System.err);
}
updateRedoState();
undoAction.updateUndoState();
}
void updateRedoState() ...{
if (undoManager.canRedo()) ...{
setEnabled(true);
putValue(Action.NAME, "Redo"); // TODO I18N
} else ...{
setEnabled(false);
putValue(Action.NAME, "Cannot redo"); // TODO I18N
}
}
}
UndoAction getUndoAction() ...{
return undoAction;
}
RedoAction getRedoAction() ...{
return redoAction;
}
}
import java.awt. event .ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JEditorPane;
import javax.swing.KeyStroke;
import javax.swing. event .UndoableEditEvent;
import javax.swing. event .UndoableEditListener;
import javax.swing.text.JTextComponent;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
/**/ /**
* UndoWrapper is responsible for adding undo and redo support to text
* components.
*
* @author Antonio Vieiro (antonio@antonioshome.net), $Author: $
* @version $Revision: $
*/
public class UndoWrapper implements UndoableEditListener ... {
public UndoManager undoManager;
private UndoAction undoAction;
private RedoAction redoAction;
private JEditorPane textComponent;
/**//**
* Creates a new instance of UndoWrapper
*/
public UndoWrapper(JEditorPane aComponent) ...{
textComponent = aComponent;
undoManager = new UndoManager();
undoAction = new UndoAction();
redoAction = new RedoAction();
textComponent.getDocument().addUndoableEditListener(this);
textComponent.getInputMap()
.put((KeyStroke) undoAction.getValue(Action.ACCELERATOR_KEY),
"undo");
textComponent.getInputMap()
.put((KeyStroke) redoAction.getValue(Action.ACCELERATOR_KEY),
"redo");
textComponent.getActionMap().put("undo", undoAction);
textComponent.getActionMap().put("redo", redoAction);
}
public void undoableEditHappened(UndoableEditEvent e) ...{
undoManager.addEdit(e.getEdit());
undoAction.updateUndoState();
redoAction.updateRedoState();
}
/**//**
* UndoAction is the Action responsible for handling the undo operation.
*/
class UndoAction extends AbstractAction ...{
public UndoAction() ...{
super("Cannot undo"); // TODO: I18N
setEnabled(false);
putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl Z"));
}
public void actionPerformed(ActionEvent e) ...{
try ...{
undoManager.undo();
} catch (CannotUndoException cue) ...{
// TODO: Use logging?
cue.printStackTrace(System.err);
}
updateUndoState();
redoAction.updateRedoState();
}
void updateUndoState() ...{
if (undoManager.canUndo()) ...{
setEnabled(true);
putValue(Action.NAME, "Undo"); // TODO I18N
} else ...{
setEnabled(false);
putValue(Action.NAME, "Cannot undo"); // TODO I18N
}
}
}
/**//**
* RedoAction is the Action responsible for handling the redo operation.
*/
class RedoAction extends AbstractAction ...{
public RedoAction() ...{
super("Cannot redo"); // TODO I18N
setEnabled(false);
putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl Y"));
}
public void actionPerformed(ActionEvent e) ...{
try ...{
undoManager.redo();
} catch (CannotRedoException cre) ...{
// TODO: Use logging?
cre.printStackTrace(System.err);
}
updateRedoState();
undoAction.updateUndoState();
}
void updateRedoState() ...{
if (undoManager.canRedo()) ...{
setEnabled(true);
putValue(Action.NAME, "Redo"); // TODO I18N
} else ...{
setEnabled(false);
putValue(Action.NAME, "Cannot redo"); // TODO I18N
}
}
}
UndoAction getUndoAction() ...{
return undoAction;
}
RedoAction getRedoAction() ...{
return redoAction;
}
}