JTextPane 的 undo 、 redo
实现文本框输入内容的单条记录撤销,重做,通过按钮实现
以及通过JList的多条撤销、重做操作(类似PS)
昨天还在为自己写不出代码怎么办而伤心,没想到今天上午就实现了,并且还完善了功能:
可以在撤销一些操作后,继续编辑文本框,同时给Jlist添加渲染。
代码如下:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package UndoText; import com.sun.media.sound.ModelAbstractChannelMixer; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextPane; import javax.swing.JToolBar; import javax.swing.ListSelectionModel; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.undo.UndoManager; import javax.swing.undo.UndoableEdit; /** * * @author Administrator */ //实现文本框的撤销、重做 public class UndoTextFrame extends JFrame { JPanel undoListJPanel = new JPanel(); JList undoList = new JList(); JScrollPane undoScrollPane = new JScrollPane(undoList); DefaultListModel listModel = new DefaultListModel<>(); UndoManager um = new UndoManager(); int[] undoIndexs; int indexF, indexS; public UndoTextFrame() { setTitle("sample"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new BorderLayout()); setSize(640, 480); setLocationRelativeTo(this); getContentPane().add(new textPanel(), BorderLayout.CENTER); getContentPane().add(undoListPanel(), BorderLayout.WEST); } public JPanel undoListPanel() { undoListJPanel.setLayout(new BorderLayout()); undoList.setModel(listModel); undoList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); undoList.setFixedCellWidth(100); // undoIndexs = new int[indexS]; undoScrollPane.setPreferredSize(new Dimension(100, 400)); undoScrollPane.setBorder(BorderFactory.createTitledBorder("Undo")); undoScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); undoScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); undoListJPanel.add(undoScrollPane, BorderLayout.NORTH); UndoListManager(); return undoListJPanel; } public void UndoListManager() { undoList.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent lse) { System.out.println("F:" + indexF); System.out.println("S:" + indexS); if (undoList.getValueIsAdjusting()) { indexS = undoList.getSelectedIndex(); } else { indexF = undoList.getSelectedIndex(); } undoIndexs = new int[undoList.getLastVisibleIndex()]; for (int j = 0; j < indexS; j++) { undoIndexs[j] = undoList.getSelectedIndex(); } MyRenderer renderer = new MyRenderer(undoIndexs, Color.PINK); undoList.setCellRenderer(renderer); if (indexF < indexS) { for (int i = indexF; i < indexS; i++) { if (um.canRedo()) { um.redo(); } } } else if (indexF > indexS) { for (int i = indexF; i > indexS; i--) { if (um.canUndo()) { um.undo(); } } } } }); } //quesion:textPane setLineCrap class textPanel extends JPanel { private JTextPane textPane = new JTextPane(); private JScrollPane scrollTextPane1 = new JScrollPane(textPane); // private JLabel textTitle = new JLabel("TextPane"); JPanel header = new JPanel(); JToolBar toolBar = new JToolBar(); JButton undoButton = new JButton("undo"); JButton redoButton = new JButton("redo"); public textPanel() { setLayout(new BorderLayout()); textPane.setEditable(true); textPane.setToolTipText("textPane"); scrollTextPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); scrollTextPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); toolBar.add(redoButton); toolBar.add(undoButton); toolBar.setFloatable(false); header.setLayout(new BorderLayout()); header.add(toolBar, BorderLayout.CENTER); add(header, BorderLayout.NORTH); add(scrollTextPane1, BorderLayout.CENTER); initAction(); } public void initAction() { textPane.getDocument().addUndoableEditListener(new UndoableEditListener() { @Override public void undoableEditHappened(UndoableEditEvent uee) { um.addEdit((UndoableEdit) uee.getEdit()); listModel.addElement(textPane.getText().toString().charAt(textPane.getText().length() - 1)); MyRenderer renderer = new MyRenderer(textPane.getText().length() - 1, Color.yellow); undoList.setCellRenderer(renderer); textPane.addKeyListener(new KeyAdapter() { @Override public void keyTyped(KeyEvent ke) { for (int k = indexS + 1; k < undoList.getModel().getSize(); k++) { listModel.removeElementAt(k); } } }); indexF = listModel.getSize() - 1; indexS = listModel.getSize() - 1; } }); undoButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { if (um.canUndo()) { um.undo(); } } }); redoButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { if (um.canRedo()) { um.redo(); } } }); } } //Jlist render class MyRenderer extends DefaultListCellRenderer { private Font font1; private Font font2; private Color rowcolor; private int row; private int[] rows; private DefaultListModel model; public MyRenderer() { this.font1 = getFont(); this.font2 = font1.deriveFont((float) (font1.getSize() + 10)); } public MyRenderer(int row, Color color) { this.rowcolor = color; this.row = row; } public MyRenderer(int[] rows, Color color) { this.rowcolor = color; this.rows = rows; } public MyRenderer(Color rowcolor, DefaultListModel model) { this.rowcolor = rowcolor; this.model = model; } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (rows == null) { if (index == row) { setBackground(this.rowcolor); //setFont(getFont().deriveFont((float) (getFont().getSize() + 2))); } } else { for (int i = 0; i < rows.length; i++) { if (index <= rows[i]) { setBackground(this.rowcolor); } } } return this; } } public static void main(String[] args) { new UndoTextFrame().setVisible(true); } }