作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试撤消 JEditorPane 中的 setText() 方法效果。这是我的代码:
public final class UndoManagerTestForJEditorPane {
private final JEditorPane editor = new JEditorPane();
private final UndoManager undoManager = new UndoManager();
public JComponent makeUI() {
editor.setContentType("text/html");
HTMLDocument document = (HTMLDocument) editor.getDocument();
document.addUndoableEditListener(undoManager);
editor.setText("Hello");
JPanel p = new JPanel();
p.add(new JButton(new AbstractAction("undo") {
@Override
public void actionPerformed(ActionEvent e) {
if (undoManager.canUndo()) {
undoManager.undo();
}
}
}));
p.add(new JButton(new AbstractAction("redo") {
@Override
public void actionPerformed(ActionEvent e) {
if (undoManager.canRedo()) {
undoManager.redo();
}
}
}));
p.add(new JButton(new AbstractAction("setText(new Date())") {
@Override
public void actionPerformed(ActionEvent e) {
String str = new Date().toString();
editor.setText(str);
}
}));
Box box = Box.createVerticalBox();
box.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
box.add(makePanel("Default", editor));
JPanel pp = new JPanel(new BorderLayout());
pp.add(box, BorderLayout.NORTH);
pp.add(p, BorderLayout.SOUTH);
return pp;
}
private static JPanel makePanel(String title, JComponent c) {
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createTitledBorder(title));
p.add(c);
return 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 UndoManagerTestForJEditorPane().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
默认行为通过四个步骤完成:
1) 什么也没做,光标甚至没有移动..
2) 光标向下移动到插入的单词下方近 10 行..
3)文字消失了..
4)旧文本终于出现了..
因此,除了这些步骤之外,我们是否可以只使用一个撤消步骤来完成此操作,如 JTextField JTextArea setText() & UndoManager 的链接中所示。 ,但是使用 JEditorPane ?
在 JEditorPane 上调用 setText() 时,JEditorPane 的替换方法未执行的问题...
请帮忙吗?
谢谢
最佳答案
您可以使用扩展 AbstractUndoableEdit
的单独类(如果您只需使用一个类中的信息进行编辑,则可以嵌套以直接访问必要的 GUI 元素)来完成此操作。您可以保存在一次undo
操作后要加载的确切旧状态,以及在redo
操作后要重新加载的确切新状态。然后,您可以通过在 State
类中覆盖 redo
和 undo
方法来直接在它们中设置正确的值。这可能看起来像这样:
public final class UndoManagerTestForJEditorPane {
private final JEditorPane editor = new JEditorPane();
private final UndoManager undoManager = new UndoManager();
public JComponent makeUI() {
editor.setContentType("text/html");
HTMLDocument document = (HTMLDocument) editor.getDocument();
//document.addUndoableEditListener(undoManager); -> Not used anymore
editor.setText("Hello");
JPanel p = new JPanel();
p.add(new JButton(new AbstractAction("undo") {
@Override
public void actionPerformed(ActionEvent e) {
if (undoManager.canUndo()) {
undoManager.undo();
}
}
}));
// New class to hold the state and load the correct string
class State extends AbstractUndoableEdit
{
String oldText;
String newText;
State(String oldText, String newText)
{
this.oldText = oldText;
this.newText = newText;
}
@Override
public void undo() throws CannotUndoException {
editor.setText(oldText);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void redo() throws CannotRedoException {
editor.setText(newText);
}
@Override
public boolean canRedo() {
return true;
}
}
p.add(new JButton(new AbstractAction("redo") {
@Override
public void actionPerformed(ActionEvent e) {
if (undoManager.canRedo()) {
undoManager.redo();
}
}
}));
p.add(new JButton(new AbstractAction("setText(new Date())") {
@Override
public void actionPerformed(ActionEvent e) {
String str = new Date().toString();
// Add a new edit by saving the old string (by calling getText) and the new string 'str'
undoManager.addEdit(new State(editor.getText(), str));
editor.setText(str);
}
}));
Box box = Box.createVerticalBox();
box.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
box.add(makePanel("Default", editor));
JPanel pp = new JPanel(new BorderLayout());
pp.add(box, BorderLayout.NORTH);
pp.add(p, BorderLayout.SOUTH);
return pp;
}
private static JPanel makePanel(String title, JComponent c) {
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createTitledBorder(title));
p.add(c);
return 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 UndoManagerTestForJEditorPane().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
关于java - 一步而不是三步撤消 JEditorPane 的 setText() 方法的效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26983546/
我是一名优秀的程序员,十分优秀!