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);

    }
}


 

原文地址:https://www.cnblogs.com/james1207/p/3285621.html