gpt4 book ai didi

java - 一步而不是三步撤消 JEditorPane 的 setText() 方法的效果

转载 作者:行者123 更新时间:2023-12-01 12:16:19 25 4
gpt4 key购买 nike

我正在尝试撤消 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 类中覆盖 redoundo 方法来直接在它们中设置正确的值。这可能看起来像这样:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com