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); }
}
JTextPane 的 undo 、 redo的更多相关文章
- MySQL,MariaDB:Undo | Redo [转]
本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...
- iOS: 为画板App增加 Undo/Redo(撤销/重做)操作
这个随笔的内容以上一个随笔为基础,(在iOS中实现一个简单的画板),上一个随笔实现了一个简单的画板: 今天我们要为这个画板增加Undo/Redo操作,当画错了一笔,可以撤销它,或者撤销之后后悔了, ...
- [转]MySQL日志——Undo | Redo
本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...
- 从Undo,Redo谈命令模式
一般的应用软件中,通常会提供Redo和Undo的操作,比如Paint.NET中的动作面板,Word中的撤销重做,一般我们按Ctrl-Z即可回退到上次操作. 要实现上面的这一功能,最直观的想法就是,我们 ...
- 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 ...
- 【转载】MySQL 日志 undo | redo
本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...
- MySQL InnoDB存储引擎undo redo解析
本文介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo Log Undo Log 为了实现事务原子,在MySQL数据库InnoDB存储引擎,还使用Undo Log(简称:MVCC ...
- MySQL日志Undo&Redo
00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC). - 事务的原子性(Atomi ...
- MySql Undo Redo
Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC). - 事务的原子性(Atomicity) ...
- 转:C#中Undo/Redo的一个简易实现
一个比较常见的改进用户体验的方案是用Redo/Undo来取代确认对话框,由于这个功能比较常用,本文简单的给了一个在C#中通过Command模式实现Redo/Undo方案的例子,以供后续查询. clas ...
随机推荐
- log4j 将日志记录到数据库
需要以下jar包: ---log4j commons-loggin-1.1.1.jar log4j-1.2.16.jar ---mysql mysql-connector-java-5.1.15-bi ...
- css显示省略号
white-space:nowrap;overflow:hidden;text-overflow:ellipsis; <!-- 就这三句,,,嘿嘿....->
- SQL Server索引 - 索引(物化)视图 <第九篇>
一.索引视图基本概念 索引视图实际上是一种将一组唯一值“物化”为群集索引形式的视图,所为物化就是几乎和表一样,其数据也是会存储一份的(会占用硬盘空间,但是查询速度快,例如可以将count(),sum( ...
- java设计模式--行为型模式--备忘录模式
备忘录模式,我们平常所做的备忘录么.还得深深研究哦. 备忘录模式: 备忘录模式 概述 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状 ...
- hdu 1987-How many ways(dp)
解析:假设机器人在(x,y)这个点,能量为power,那么可以到达它右下角曼哈顿距离小于等于power的地方,再以该点为起点继续搜索. 代码如下: #include<cstdio> #in ...
- Unity 手指触摸的方向(单手)
最近写了一个跑酷游戏,总结下里面的知识点:O(∩_∩)O~ using UnityEngine; using System.Collections; public class Demo : MonoB ...
- onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
有了前几篇的基础,现在可以正式开始onvif的实现工作,其中一项非常重要的部分就是视频流的对接,即能够在符合onvif标准的监控客户端软件里接收到设备端NVT发来的RTSP视频流.这里,我所用的客户端 ...
- FineUI
window间传值: Window1.GetSaveStateReference(new string[] { TextBox1.ClientID, ak.ClientID })收 ActiveWin ...
- asp.net + Jquery 实现类似Gridview功能 (一)
不知不觉2015年就过去一半了,由于过年前后公司人员陆续离职(这个...),项目忙不过来,从过年来上班就一直在忙,最近项目终于告一段落,开始步入正轨(不用天天赶项目了).所以最近才有时间写这个东西,可 ...
- PHP学习笔记三
<?php $a=56; $b=++$a; //等价于 $a=$a+1; $b=$a; /////2. $e=false||true;//结果为true $f=false or true;//输 ...