[转载]用Java制作十六进制编辑器

用Java制作十六进制编辑器
screen.width-500)this.width=screen.width-500;" alt="按此在新窗口浏览图片" src="http://img.pconline.com.cn/images/bbs4/200611/18/1163812032635.jpg" />
screen.width-500)this.width=screen.width-500;" alt="按此在新窗口浏览图片" src="http://img.pconline.com.cn/images/bbs4/200611/18/1163812047522.jpg" />
分 析:对于同一段数据值,用两种方式来显示和编辑,则用MVC(模型-视图-控制器)模式来作为主结构是再合适不过的了。模型的作用是保存真实的数据值,同 时提供若干提取和修改数据的方法;视图是数据在用户界面上的表示,控制器定义用户界面对用户输入的响应方式,即把用户的键盘动作和鼠标动作解释成模型中的 数据操作方法。出于简化的考虑,本例中把视图和控制器合并到了一起。

模型的设计:编辑器必须能处理任意字节块,所以考虑模型内用字节数组来存储数据;要提供在指定偏移处增加、修改和删除字节块的操作;当模型内的数据被改变时要及时通知视图来刷新用户界面或其它感兴趣的对象;

视图和控制器的设计:

对 于常规编辑的视图,只需把模型中的字节数组转化成String,使用一个文本区域组件JTextArea来显示即可。JTextArea本身也是一个遵循 MVC模式的Swing组件,它的控制器即可被用来作为我们自己的控制器,监听它的文本增加、修改和删除事件,从而控制我们自己的数据模型;

对 于16进制编辑的视图,同样可以用JTextArea来显示,只是在显示之前,要对模型中的数据进行若干加工,如每行显示16个字节,每行都要加表示偏移 量的头,行尾要加这一行数据的字符串表示形式。它的控制器则不能简单的利用JTextArea的控制器了,为了保证显示格式不被打乱,需要监视它的所有光 标移动事件、键盘击键事件等。同时,为了保持与UltraEdit的十六进制编辑器的功能一致性,对它的数据的增加、删除功能提供两个按钮,询问用户操作 的字节数,如果增加n个字节,则在输入光标处插入n个十六进制值为20的字符(字符空格)。

十六进制编辑器的主要结构请参见下图,由于篇幅关系,图中只列出了十六进制编辑部分,常规编辑部分请读者自行设计:

screen.width-500)this.width=screen.width-500;" alt="按此在新窗口浏览图片" src="http://img.pconline.com.cn/images/bbs4/200611/18/1163812088049.jpg" />
下面分别就几个主要的方法的功能和主要流程加以说明。

HexPane.displayValue方法,它主要完成数据的显示工作:

public void diplayValue() {
canvas.setText("");

byte[] data = model.getData();
int dataLen = data.length;

// 把字节数组按每16个字节为一块进行分块;
int lines = dataLen / 16 + 1;
int tails = dataLen % 16;
int offset = 0;
for(int i = 0; i < lines; i ++) {
// 在canvas的新行上加上行标,如“000020:”,表示这是第3行;
canvas.append(lineHead(i));
canvas.append(" ");

// 把数据块的字节值用Integer.toHexString()转化成长度为48的字符串,
// 数据块不足16个字节的,在字符串后用空格补足;把字符串加入canvas的当前行;
for(offset = 0; offset < 16; offset ++) {
canvas.append((i < lines - 1 || offset < tails) ?
byteHex(data[i * 16 + offset]) : " ");
canvas.append(" ");
}
canvas.append("| ");

// 把数据块构造成字符串,添在canvas的行尾;
canvas.append(bytesToStr(data, i * 16, (i == lines - 1) ? tails : 16));
if(i < lines - 1) ta.append("n");
};
}
这 里的bytesToStr方法有两点特别需要注意的地方,一是不可见字符,如果不屏蔽这些字符,则我们的编辑器的显示格式会被搞得乱七八糟,一般可以把 ASCII值0到0×1F和0×7F的33个字符全部替换成0×2E,即字符小数点。二是中文字符,因为每个中文字符是2个字节,如果数据块的起始字节一 个中文字符的一半(可以用ASCII值大于0×7F来判断)的时候,将会显示一串乱字符,处理方法是不显示该字节。

为叙述方便,我们把 canvas中显示每一行的行标的区域称为标号区,它宽度固定为8个字符(6个字符显示标号,一个冒号和一个空格);把canvas中显示十六进制数据的 区域称为数据区,宽度固定为48个字符(每字节用十六进制显示为2字符宽,两两之间有一个空格,则总宽为16×3);把canvas中每行以字符串形式显 示数据的区域称为字串值区,宽度不定(最短为8个字符――全中文状态,最长为16个字符――全英文状态)。

我们的canvas是一个 Swing的文本组件,我们不但用它显示数据,还显示标号和字串值,而只有数据才是允许被编辑的,所以我们给canvas增加了 CaretListener和KeyListener,当输入光标落在不允许编辑的区域时,我们要把光标自动移到最近的允许编辑的地方去。

public void caretUpdate(CaretEvent e) {
// 这个方法在输入光标移动时被触发

// 输入光标相对canvas第0行第0个字符的偏移量
int pos = canvas.getCaretPosition();
int line = 0;
int startPos = 0;
try {
// 输入光标位于第几行
line = canvas.getLineOfOffset(pos);

// 当前行的第0个字符相对canvas第0行第0个字符的偏移量
startPos = canvas.getLineStartOffset(line);
}catch(BadLocationException exception) { }

if(pos - startPos < 8) // 输入光标在标号区
// 移动到数据区第0个字符
canvas.setCaretPosition(startPos + 8);
else if(pos - startPos > 54) // 输入光标在字串值区
// 移动到数据区最后一个字节
canvas.setCaretPosition(startPos + 54);
else if((pos - startPos - 8) % 3 == 2) { // 在数据区的间隙空格上
// 往前移一个字符
canvas.setCaretPosition(pos - 1);
}
}

public void keyPressed(KeyEvent e) { // 当键盘被按下时触发
int key = e.getKeyCode();
switch(key) { // 如果是方向键则移动输入光标
case KeyEvent.VK_LEFT:
setCaretPrev();
break;
case KeyEvent.VK_RIGHT:
setCaretNext();
break;
case KeyEvent.VK_UP:
setCaretPrevLine();
break;
case KeyEvent.VK_DOWN:
setCaretNextLine();
break;
default:
return;
}
}

public void keyTyped(KeyEvent e) {
// 在键盘的可见字符被输入时触发
char ch = e.getKeyChar();
if((ch >= ‘0′ && ch <= '9') || (ch >= ‘a’ && ch <= 'f')
|| (ch >= ‘A’ && ch <= 'F')) {
int pos = canvas.getCaretPosition(); // 先获取光标位置的信息
int line = 0, startPos = 0;
try {
line = canvas.getLineOfOffset(pos);
startPos = canvas.getLineStartOffset(line);
}catch(BadLocationException exception) { }
char c = (char)0;
if((pos - startPos - 8) % 3 == 0) { // 一个字节值的前4位
c = canvas.getText(pos + 1, 1).charAt(0);
model.updateBytes(line * 16 + (pos - startPos - 8) / 3,
Byte.parseByte("" + (char)((ch << 4) + c), 16));
}else{ // 一个字节值的后4位
c = canvas.getText(pos - 1, 1).charAt(0);
model.updateBytes(line * 16 + (pos - startPos - 8) / 3,
Byte.parseByte("" + (char)((c << 4) + ch), 16));
setCaretNext();
}
}
}
到这里为止,十六进制编辑的显示和输入控制已经基本完成了,下面开始解决数据Model的问题。Model是用来保存数据的,并且提供增加、修改和删除数据的方法,还要维护一个监听者组,在数据被改变时向监听者发出通知。这里提供一个简单的实现版本。

import javax.swing.event.EventListenerList;

public class DefaultBytesModel implements BytesModel{
// 监听者组
private EventListenerList listeners = new EventListenerList();
private byte[] data = null;

public DefaultBytesModel (byte[] bytes) {
data = new byte[bytes.length];
}

public void addModelListener(BytesModelListener listener) {
listeners.add(BytesModelListener.class, listener);
}

public void removeModelListener(BytesModelListener listener) {
listeners.remove(BytesModelListener.class, listener);
}

/**
* 通知监听者
*/
public void fireDataInserted(int offset, byte[] bytes) {
Object[] ls = listeners.getListenerList();
for(int i = ls.length - 2; i >= 0; i -= 2) {
if(ls[i] == BytesModelListener.class) {
((BytesModelListener)ls[i + 1]).bytesInserted(offset, bytes);
}
}
}

/**
* 在指定的偏移处插入数据
*/
public void insertBytes(int offset, byte[] bytes) {
if(offset < 0 || offset >= data.length) return;
if(bytes.length == 0) return;

// 扩充字节数组的长度并用新值填充
byte[] newBytes = new byte[bytes.length + data.length];
System.arraycopy(data, 0, newBytes, 0, offset);
System.arraycopy(bytes, 0, newBytes, offset, bytes.length);
System.arraycopy(data, offset, newBytes, offset + bytes.length, data.length - offset);
data = newBytes; // 用新的数据替代旧数据,然后通知监听者
fireDataInserted();
}

public byte[] getData() {
return data;
}
}
限于篇幅,这里只简单列出了部分方法,并且并没有对它们进行严格的有效的差错校验和违例控制。其它的数据操作方法与此类似,读者可以自行编制并完善。

本文分析了一个用Java实现的十六进制编辑器的设计过程,并提供了部分实现代码。从这个实例,可以学习到Java的事件处理的相关知识,促进对文本类组件――这种Swing中最复杂的组件的了解。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130756/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/374079/viewspace-130756/

程序员常用的几个效率小工具,可好用了! 程序员常用的几个小工具,可好用了! 阅读详情

相关推荐

软件修改工具----盘点那些免费的windows系统下的16进制编辑器 软件修改好帮手

我们在修改软件或者有些分区文件时。不可避免的要使用一些进制修改工具。网络很多工具有的是收费的。另外有的功能不太全面。今天将详细解析下那些在windows下使用的免费进制修改工具HxD编辑器中文版是一款专业高效的十六进制编辑器和磁盘数据编辑器。HxD编辑器中文版功能全面,绿色小巧,支持对主存储器(RAM)的原始磁盘编辑和修改,还能够对任意文件进行16进制编辑。除了主存储器(RAM)的原始磁盘编辑和修改外,还可以处理任何大小的文件。界面提供了搜索和替换,导出,校验和/摘要,插入字节模式,文件碎纸机,连接或分割文

小马哥的专栏 9753

Java十六进制编辑器实现

所谓的十六进制编辑器,就是把用十六进制的方式打开一个文件,其中读进来的每个字节被做为两个十六进制数看待,例如:   读入字节: 01101010; 分解成前后两个16进制数,每四个一组,就成了: 0110 1010 --&gt; 6 A。   所以首先我们需要把文件做为字节流读入:     File file = new File(filePath); BufferedInputS...

刘刚的空间 710

编辑器:010Editor、ultraedit、Sublime Text、Notepad++

编辑器:010Editor、ultraedit、Sublime Text、Notepad++

freeking101的博客 7万+

如何在Java中将文件转换为十六进制

一个简单的Java程序演示了如何使用String格式程序(“%02X”)将File转换为Hex值。 所附评论应不言自明。 例 package com.mkyong; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; im...

一名可爱的技术搬运工 2324

10个最流行免费的Mac OS文本编辑器

10个最流行免费的Mac OS文本编辑器

qq_44894420的博客 2万+

editplus字符转16进制_EditPlus–一款小巧功能强大的老牌代码文本编辑器

这是一款小巧功能强大的老牌代码文本编辑器,可处理文本、网页和程序语言的文字编辑器,也可以将它作为C/Java/Php等语言的简单IDE调试编辑工具软件功能语法突出显示EditPlus默认支持功能强大且可自定义的HTML,CSS,PHP,ASP,Perl,C / C ,JavaJavaScript和VBScript语法突出显示。另外,您可以创建自己的语法文件以支持其他编程语言上网功能1、无缝的We...

weixin_39590635的博客 563

PilotEdit 破解版下载|PilotEdit(文本编辑器) 中文破解版 v11.8下载(含注册机)

转载于:https://blog.csdn.net/qq_41764614/article/details/80996821 PilotEdit 破解版是一款功能非常强大、方便和可靠的文本编辑器,旨在帮助用户执行脚本,提取字符串和编辑大型文件。 PilotEdit是一个文件编辑器,可以帮助你搜索和替换多行文字,编辑FTP文件甚至是下载和上传的FTP文件和目录。 用...

vickyleexy's blog 6818

几个处理 Java 的 class 文件的工具(转载

本文转载自:http://qixinglu.com/post/some_handle_java_class_file_tools.html   一般来说手动修改二进制文件是件苦差事,有源码在手不如直接修改重新编译。但有些软件是不开源的,又想修改它的功能以便更好使用,就想反编译,但很 多代码都是混淆过的,反编译后几乎不能阅读,如果要改的的地方不是很多,比如最常做的是反转条件和替换字符串,这还...

abc123maxiaolong的专栏 633

程序员最喜欢的15款文本编辑器推荐

转载地址:http://www.cr173.com/html/50553_1.html 很多时候比如编程查看代码或者打开各种文档下我们都会用到文本编辑器,Windows自带的记事本功能很简陋并且打开大文件很慢,因此很多童鞋都会有自己喜欢的一款文本编辑器。在这里,西西挑选前15个最佳的文本编辑器,这些编辑器实际上主要适合程序员!如果觉得这些文本编辑器足够您的使用,欢迎点赞,如果还有更好的,

zhukangle的博客 28万+

推荐一款好用的代码编辑器——sublime text 2

PHP中我们一般都用zend studio,java用eclipse等,但是呢这些占用的内存和cpu一般都是挺高的,zend多的时候能占用600多兆,对于一些机器配置不太高的朋友们来说,开一个vs或者sql server 2008等大的软件,再开一个zend机器就卡卡的,今天呢给大家介绍一款消耗内存和cpu都特别小的代码编辑器,说是编辑器,其实它跟IDE差不多了,支持语法错误提示,格式化代码,多列...

weixin_30575309的博客 89

Java笔记第五篇 文本编辑器初见面

#日常唠叨#从现在开始,又要开始讲理论了,小星星努力今天写完文本编辑器之后再用2天时间写完数据类型,然后上代码,另外关于HelloWorld代码的讲解小星星会在写完运算符之后写 编译厉害归厉害,但对我们打代码的流畅度、心情舒畅度有用吗?答案是没用。相信大家用记事本编写代码之后已经心生厌烦了吧?如果这么打上上千行肯定吐血。那小星星现在给大家升级一下记事本。 升级过后的记事本叫啥名字?当然是叫超级...

weixin_30409849的博客 88

windows 实用小工具(截图、进程管理)

1. 截图 picpick:PicPick—NGWIN,一款全功能的设计工具,包含屏幕截图、图片编辑器、颜色选择器、像素标尺和其它更多的功能 2. 二进制/十六进制 十六进制(二进制)编辑器 3. process explorer:查看进程信息 process explorer 下载地址:Process Explorer v16.21 ...

weixin_30852419的博客 457

Java中的常用开发工具详解

转载:https://blog.csdn.net/han0373/article/details/79180553 Java开发人员的常用工具 java常用的开发工具。都说工欲善其事必先利其器,要想学好java这门语言,选择一款好用顺手的开发工具是必不可少的。另外面试java工作时开发工具的使用也是一个重要的考核点。 要想...

十豆三展的博客 1013

UE编辑器

UltraEdit的用途 用做普通文本文件编辑器(.txt .bat .conf .ini等) 用做.doc文件编辑器(不过,不是msword的文档,其实也是文本文件,我不知道为什么叫doc) 用做c, c++, java, jsp, html, xml等的源代码编辑器 (以上文件可以是本地的,也可以是通过FTP方式操作远程的文件) 对文本文件进行按行排序,排序的方式是可以定义的。 对1...

weixin_34104341的博客 98

UltraEdit-文本编辑器Mac绿色版

前言 更多内容,请访问我的 个人博客。 简介: Ultraedit是一款在Windows系统中非常出名的文本编辑器,可以编辑文本、十六进制、ASCII 码,完全可以取代其他文本工具,同时还支持许多开发语言,如 C, Objective C, Javascript, XML, PHP, Perl, Python等,并可同时编辑多个文件,而且即使开启很大的文件速度也不会慢。 功能特点: 可...

weixin_34269583的博客 673
上一篇: [转载]tomcat中配置DataSourceRealm
下一篇: [转载]Jboss入门精简篇
congji3817
博客等级 码龄10年 15粉丝 588原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值