实现文本框输入内容的单条记录撤销,重做,通过按钮实现

以及通过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); }
}

JTextPane 的 undo 、 redo的更多相关文章

  1. MySQL,MariaDB:Undo | Redo [转]

    本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...

  2. iOS: 为画板App增加 Undo/Redo(撤销/重做)操作

    这个随笔的内容以上一个随笔为基础,(在iOS中实现一个简单的画板),上一个随笔实现了一个简单的画板:   今天我们要为这个画板增加Undo/Redo操作,当画错了一笔,可以撤销它,或者撤销之后后悔了, ...

  3. [转]MySQL日志——Undo | Redo

    本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...

  4. 从Undo,Redo谈命令模式

    一般的应用软件中,通常会提供Redo和Undo的操作,比如Paint.NET中的动作面板,Word中的撤销重做,一般我们按Ctrl-Z即可回退到上次操作. 要实现上面的这一功能,最直观的想法就是,我们 ...

  5. Undo/Redo for Qt Tree Model

    Undo/Redo for Qt Tree Model eryar@163.com Abstract. Qt contains a set of item view classes that use ...

  6. 【转载】MySQL 日志 undo | redo

    本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...

  7. MySQL InnoDB存储引擎undo redo解析

    本文介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo Log Undo Log 为了实现事务原子,在MySQL数据库InnoDB存储引擎,还使用Undo Log(简称:MVCC ...

  8. MySQL日志Undo&Redo

    00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC). - 事务的原子性(Atomi ...

  9. MySql Undo Redo

    Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC). - 事务的原子性(Atomicity) ...

  10. 转:C#中Undo/Redo的一个简易实现

    一个比较常见的改进用户体验的方案是用Redo/Undo来取代确认对话框,由于这个功能比较常用,本文简单的给了一个在C#中通过Command模式实现Redo/Undo方案的例子,以供后续查询. clas ...

随机推荐

  1. 关于css浮动的一些总结

    首先给浮动一个定义吧 浮动可以理解为让某个div元素脱离标准流,漂浮在标准流之上,和标准流不是一个层次. 从测试中来看 元素之间的浮动关系是根据上一个元素来判断的如果上一个元素是浮动的它会跟在浮动元素 ...

  2. Search Insert Position 解答

    Question Given a sorted array and a target value, return the index if the target is found. If not, r ...

  3. Train Problem I(栈)

    Train Problem I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  4. OpenStack 部署总结之:在CentOS 6.5上使用RDO单机安装icehouse(Ml2+GRE)

    本文主要介绍怎样在CentOS6.5上通过RDO来安装icehouse,因为安装的过程中涉及的软件较多,以及依赖关系比較复杂,建议使用一个全新的操作系统来进行安装. 安装步骤详细例如以下 (1)安装操 ...

  5. Excel中将时间格式转化成时间戳格式

    时间戳转成正常日期的公式:C1=(A1+8*3600)/86400+70*365+19其中A1表示当时的1249488000时间戳数值其中C1就是所需的日期格式,C1单元格属性改成日期格式就可以了.正 ...

  6. JS 不定函数参数argument的用法

    本篇文章只要是对js的隐含参数(arguments,callee,caller)使用方法进行了介绍. arguments arguments 该对象代表正在执行的函数和调用它的函数的参数. [func ...

  7. UIView的clipsTobounds属性

    这里的clip是修剪的意思,bounds是边界的意思,合起来就是:如果子视图的范围超出了父视图的边界,那么超出的部分就会被裁剪掉.该属性在实际工程中还是非常实用的,必须要了解清楚.

  8. ASP.NET MVC中移除冗余Response Header

    本文主要介绍如何优化ASP.NET MVC使用IIS时Response Header中的不必要的信息 默认的,创建一个ASP.NET MVC项目,会在Response Header中包含一些敏感的信息 ...

  9. nodejs中的 Cannot read property'text' of undefined 问题

    接触nodejs时间不久,最近遇到了这个问题,经过查阅资料以及百度终于解决了.

  10. Single Number,Single Number II

    Single Number Total Accepted: 103745 Total Submissions: 218647 Difficulty: Medium Given an array of ...