gpt4 book ai didi

java - JTextArea setText() & UndoManager

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:10:11 25 4
gpt4 key购买 nike

我正在使用 UndoManager 来捕获我的 JTextArea 中的更改。

setText() 方法会删除所有内容,然后粘贴文本。当我撤消时,我首先看到一个空白区域,然后它会显示它之前的文本。

如何重现:

  1. 运行以下代码
  2. 点击setText()按钮
  3. CTRL+Z 撤消(您会看到一个空的文本区域!)
  4. CTRL+Z 撤消(您将看到实际的先前文本)

我想跳过 3).

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.Document;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;

import java.awt.event.ActionEvent;
import javax.swing.JButton;
import java.awt.event.ActionListener;

@SuppressWarnings("serial")
public class JTextComponentSetTextUndoEvent extends JFrame
{
JTextArea area = new JTextArea();

public JTextComponentSetTextUndoEvent()
{
setSize(300, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().setLayout(null);

area.setText("Test");
area.setBounds(0, 96, 146, 165);
getContentPane().add(area);

JButton btnSettext = new JButton("setText()");
btnSettext.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
area.setText("stackoverflow.com");
}
});
btnSettext.setBounds(0, 28, 200, 50);
getContentPane().add(btnSettext);

final UndoManager undoManager = new UndoManager();
Document doc = area.getDocument();

doc.addUndoableEditListener(new UndoableEditListener()
{
public void undoableEditHappened(UndoableEditEvent evt)
{
undoManager.addEdit(evt.getEdit());
}
});

area.getActionMap().put("Undo", new AbstractAction("Undo")
{
public void actionPerformed(ActionEvent evt)
{
try
{
if (undoManager.canUndo())
{
undoManager.undo();
}
} catch (CannotUndoException e)
{
}
}
});

area.getInputMap().put(KeyStroke.getKeyStroke("control Z"), "Undo");

area.getActionMap().put("Redo", new AbstractAction("Redo")
{
public void actionPerformed(ActionEvent evt)
{
try
{
if (undoManager.canRedo())
{
undoManager.redo();
}
} catch (CannotRedoException e)
{
}
}
});

area.getInputMap().put(KeyStroke.getKeyStroke("control Y"), "Redo");
}

public static void main(String[] args)
{
new JTextComponentSetTextUndoEvent().setVisible(true);
}
}

最佳答案

默认情况下,javax.swing.undo.UndoManager 会保留每个可撤消的编辑,包括删除原始文本的编辑(您的第三步)。无法访问单个编辑,但您可以使用引用的方法分组编辑 here .关于您的示例的一些附加说明:

  • 为了获得更好的跨平台结果,请按照建议使用 getMenuShortcutKeyMask() here .

  • 使用 layout ;如有必要,调用 setSize() after pack(),如图所示 here .

  • Swing GUI 对象应该event dispatch thread 上构造和操作.

Code :

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.Document;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;

@SuppressWarnings("serial")
public class JTextComponentSetTextUndoEvent extends JFrame {

private static final int MASK
= Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private JTextArea area = new JTextArea();
private UndoManager undoManager = new UndoManager();

public JTextComponentSetTextUndoEvent() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
area.setText("Test");
add(area);
JButton btnSettext = new JButton("setText()");
btnSettext.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
area.setText("stackoverflow.com");
}
});
add(btnSettext, BorderLayout.PAGE_END);
Document doc = area.getDocument();
doc.addUndoableEditListener(new UndoableEditListener() {
@Override
public void undoableEditHappened(UndoableEditEvent e) {
undoManager.addEdit(e.getEdit());
System.out.println(e);
}
});
area.getActionMap().put("Undo", new AbstractAction("Undo") {
@Override
public void actionPerformed(ActionEvent evt) {
try {
if (undoManager.canUndo()) {
undoManager.undo();
}
} catch (CannotUndoException e) {
System.out.println(e);
}
}
});
area.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, MASK), "Undo");
area.getActionMap().put("Redo", new AbstractAction("Redo") {
@Override
public void actionPerformed(ActionEvent evt) {
try {
if (undoManager.canRedo()) {
undoManager.redo();
}
} catch (CannotRedoException e) {
System.out.println(e);
}
}
});
area.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Y,MASK), "Redo");
pack();
setSize(320, 240);
setLocationRelativeTo(null);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
new JTextComponentSetTextUndoEvent().setVisible(true);
}
});
}
}

关于java - JTextArea setText() & UndoManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24433089/

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