今天我想要分享的是一个用java写的一个记事本程序。我知道现在市面上有各种各样的记事本了,但是我发现有的写的功能不够完善,或者是代码层次结构不够清晰,有的甚至看了之后云里雾里的,有的还不乏了非常明显的bug,我现在分享的这个记事本程序基本上把代码层次都抽分出来,并修复了一些已知bug。先看一下界面效果图,快捷键我都已经全部加上了,只是没有在界面上标明而已,一般常用的那几个快捷键都直接使用即可!

该程序主要功能有:打开、保存、另存为、退出、新建、黏贴、复制、全选、剪切、删除、查找、替换、转到、修改字体、自动换行、查看帮助等功能。目前未完善的功能有自动显示标题。

首先我是使用了swt这个插件在eclipse中开发的,该程序在跨平台使用时会有稍许不同之处!安装swt在这里就不再重复说明,我们直接来新建工程吧!

一、新建一个swt工程,命名为Note,这个时候我们说需要依赖的swt中的jar包会自动导入了,如果你的有导入jar包的问题,你也可以手工导入jar包。

之后建立3个包来存放我们的类:dialog(主要是一些弹窗类的实现)、noteUi(存放主要的实现类)、Utils(抓哟存放一些公有的工具文件)。

二、在noteUI包中新建一个住类,我们命名为Note1.java好了,额,忘记说了,这个Note1.java是一个swt的new Appliction Windows的类,在里面就可以通过design来制作这个窗口的布局,主要就是menu bar,等,具体布局方式可以看这个图:

布局写好之后,我们就可以添加各种事件了

三、添加快捷键

//快捷键部分

open.setAccelerator(SWT.CTRL |'o');

save_file.setAccelerator(SWT.CTRL |'s');

quit.setAccelerator(SWT.CTRL |'p');

select_all.setAccelerator(SWT.CTRL + 'a');

new_file.setAccelerator(SWT.CTRL |'n');

new_file.setAccelerator(SWT.CTRL + 'N'); //新建文件快捷键

undo.setAccelerator(SWT.CTRL + 'Z'); //撤销快捷键

cut.setAccelerator(SWT.CTRL + 'T'); //剪切快捷键

copy.setAccelerator(SWT.CTRL + 'C'); //复制快捷键

paste.setAccelerator(SWT.CTRL + 'V'); //粘贴快捷键

delete.setAccelerator(SWT.DEL); //删除快捷键

find.setAccelerator(SWT.CTRL + 'F'); //查找快捷键

find_next.setAccelerator(SWT.F3); //查找下一处快捷键

replace.setAccelerator(SWT.CTRL + 'H'); //替换快捷键

go_to.setAccelerator(SWT.CTRL + 'G'); //转到快捷键

四、我们先从简单的做起吧!,先写查看帮助吧!

MenuItem look_help = new MenuItem(menu_5, SWT.NONE);

look_help.addSelectionListener(new SelectionAdapter() {

@Override

public void widgetSelected(SelectionEvent e) {

UiUtils.showMessageDialog(shell, "帮助","欢迎查看我的博客:http://blog.csdn.net/sdksdk0!");

}

});

look_help.setText("查看帮助");当然,对于这个“关于我们”的话可以使用一个弹窗来写,新建一个swt窗口文件,那么我们可以这样来调用:这个界面是具体的实现跨越看我文末提供的源码。

MenuItem menuItem_15 = new MenuItem(menu_6, SWT.NONE);

menuItem_15.addSelectionListener(new SelectionAdapter() {

@Override

public void widgetSelected(SelectionEvent e) {

About_us as=new About_us();

as.open();

}

});

五、然后我们可以来看一个字体的设置,主要是调用系统本身的api就可以了,调用这个窗体然后来使用!更改颜色的部分我暂时只加了三种颜色,其他的颜色你可以自己加上,

//字体设置

font.addSelectionListener(new SelectionAdapter() {

@Override

public void widgetSelected(SelectionEvent e) {

FontDialog fd=new FontDialog(shell,SWT.None);

Font oldFont=getText().getFont();

if(oldFont!=null){

fd.setFontList(oldFont.getFontData());

}

FontData fontData=fd.open();

if(fontData==null){

return;

}

Color c=new Color(shell.getDisplay(),fd.getRGB().red,fd.getRGB().green,fd.getRGB().blue);

text.setForeground(c);

final Display display=Display.getDefault();

Font newFont=new Font(display,fontData);

getText().setFont(newFont);

if(oldFont!=null){

oldFont.dispose();

}

}

});六、在这个记事本的最下面一行有一个可以记录当前时间的,我们可以使用Data来写,然后通过SimpleDateFormat来格式化显示日期时间。

Label lblNewLabel = new Label(sashForm, SWT.NONE);

SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");

lblNewLabel.setText("指令汇科技欢迎您的使用,现在是:" + sdf.format(new Date()));

sashForm.setWeights(new int[] {309, 24});

七、我们可以来看一下复制、黏贴、剪切、全选的书写,其他这个应该是最简单了了,因为这个可以直接调用以下方法。全选就直接使用text.selectAll();就可以了。

MenuItem cut = new MenuItem(menu_2, SWT.NONE);

cut.addSelectionListener(new SelectionAdapter() {

@Override

public void widgetSelected(SelectionEvent e) {

getText().cut();

}

});

cut.setText("剪切");

MenuItem copy = new MenuItem(menu_2, SWT.NONE);

copy.addSelectionListener(new SelectionAdapter() {

@Override

public void widgetSelected(SelectionEvent e) {

text.copy();

}

});

copy.setText("复制");

MenuItem paste = new MenuItem(menu_2, SWT.NONE);

paste.addSelectionListener(new SelectionAdapter() {

@Override

public void widgetSelected(SelectionEvent e) {

getText().paste();

}

});

paste.setText("黏贴");

八、这个时候我们来写一下查找替换等,这个时候新建一个弹出的方法更好了,

/**

* Create contents of the dialog.

*/

private void createContents() {

shell = new Shell(getParent(), getStyle());

shell.setSize(445, 137);

shell.setLocation(780, 300);

shell.setText("\u67E5\u627E");

textContent = new Text(shell, SWT.BORDER);

textContent.addKeyListener(new KeyAdapter() {

/**

* 为查找编辑框添加事件,以同步查找按钮的更新

* 有内容则显示查找,否则显示为不可点击

*/

public void keyReleased(KeyEvent e) {

if(textContent.getText() != ""){

find_next.setEnabled(true);

chazhao = true;

}else{

find_next.setEnabled(false);

chazhao = false;

}

}

});

textContent.setBounds(99, 10, 204, 22);

find_next = new Button(shell, SWT.NONE);

find_next.setEnabled(false);

find_next.addSelectionListener(new SelectionAdapter() {

@Override

public void widgetSelected(SelectionEvent e) {

pareStr = Util.shell.getText_1(); //获取主窗口文本框内容 true

index = pareStr.indexOf(textContent.getText(),index); //获取查找串在母串中的从index处开始的位置

if(index == -1){

JOptionPane.showMessageDialog(null, "找不到\""+textContent.getText()+"\"","记事本", JOptionPane.ERROR_MESSAGE);

}

int end = index+textContent.getText().length();//获得渲染的结束位置

Util.shell.selectContent(index, end);

index = index+textContent.getText().length();

}

});

find_next.setBounds(329, 6, 99, 27);

find_next.setText("\u67E5\u627E\u4E0B\u4E00\u5904(F)");

Label lblNewLabel = new Label(shell, SWT.NONE);

lblNewLabel.setBounds(10, 10, 85, 22);

lblNewLabel.setText("\u67E5\u627E\u5185\u5BB9(&N):");

Button quxiao = new Button(shell, SWT.NONE);

quxiao.addSelectionListener(new SelectionAdapter() {

/**

* 为取消按钮设置事件

*/

public void widgetSelected(SelectionEvent e) {

shell.setVisible(false);

}

});

quxiao.setBounds(329, 65, 100, 27);

quxiao.setText("\u53D6\u6D88");

Button qufen = new Button(shell, SWT.CHECK);

qufen.addSelectionListener(new SelectionAdapter() {

/**

* 判断是否区分大小写,若是,则改变

*/

public void widgetSelected(SelectionEvent e) {

qf = qufen.getSelection();

}

});

qufen.setBounds(10, 65, 149, 27);

qufen.setText("\u533A\u5206\u5927\u5C0F\u5199(&C)");

Label label1 = new Label(shell, SWT.NONE);

label1.setText("\u66FF\u6362\u4E3A(&F):");

label1.setBounds(10, 38, 72, 22);

replaceText = new Text(shell, SWT.BORDER);

replaceText.addKeyListener(new KeyAdapter() {

/**

* 为替换编辑框添加事件,以同步替换按钮的更新

* 有内容则显示替换,否则显示为不可点击

*/

public void keyReleased(KeyEvent e) {

if(replaceText.getText() != ""){

replaceBtn.setEnabled(true);

}else{

find_next.setEnabled(false);

}

}

});

replaceText.setBounds(99, 38, 204, 22);

replaceBtn = new Button(shell, SWT.NONE);

replaceBtn.addSelectionListener(new SelectionAdapter() {

/**

* 替换按钮事件

*/

public void widgetSelected(SelectionEvent e) {

pareStr = Util.shell.getText_1(); //获取主窗口文本框内容 true

pareStr = pareStr.replaceFirst(textContent.getText(), replaceText.getText());

Util.shell.showText(pareStr);

}

});

replaceBtn.setText("\u66FF\u6362(&R):");

replaceBtn.setEnabled(false);

replaceBtn.setBounds(329, 32, 99, 27);

我们在之前的主类,即Note1中添加相应的调用就可以了,例如:replace.addSelectionListener(new SelectionAdapter() {

@Override

public void widgetSelected(SelectionEvent e) {

FindWindow fw = new FindWindow(shell,SWT.DIALOG_TRIM);

fw.open();

}

});查找替换等都是一样的,这里就不再重复说明。

九、至于跳转的话这样就可以了:

queding.addSelectionListener(new SelectionAdapter() {

/**

* 确定跳转到某行

*/

public void widgetSelected(SelectionEvent e) {

int n = Integer.parseInt(goto_line.getText());

goto_line.setText(""+ n + "");

Util.shell.gotoOneLine(1);

}

});

十、接下来就是最重要的文件打开 和保存等操作了,一般这个地方的bug最多

那我们就先来看看打开文件的操作吧,我使用的是gbk编码来读取文件的,我之前发现如果默认编码的话读取文件有乱码现象,所以我就直接加gbk了,简单粗暴

// 打开

open.addSelectionListener(new SelectionAdapter() {

@Override

public void widgetSelected(SelectionEvent e) {

FileDialog fd = new FileDialog(shell, SWT.None);

String file = fd.open();

File f = new File(file);

BufferedInputStream bis = null;

if (f.exists() && f.isFile()) {

try {

bis = new BufferedInputStream(new FileInputStream(f));

byte[] bs = new byte[1024];

int length = 0;

StringBuffer sb = new StringBuffer();

while ((length = bis.read(bs, 0, bs.length)) != -1) {

sb.append(new String(bs, 0, length,"gbk"));

}

text.setText(sb.toString());

} catch (Exception e1) {

e1.printStackTrace();

UiUtils.showMessageDialog(shell, "出错了",e1.getMessage());

} finally {

if(bis!=null){

try {

bis.close();

} catch (IOException e1) {

UiUtils.showMessageDialog(shell, "出错了",e1.getMessage());

}

}

}

} else {

UiUtils.showMessageDialog(shell, "出错了",

"文件" + f.getName() + "不存在");

}

}

});

十一、之后就是写保存文件的代码了,保存的时候有两种方法,一种是直接保存,另一种是另存为。我们采用FileOutputStream来从程序写出到文件中。

public class SaveMethod {

/**

* 将保存的两种方法分装成类,方便调用

* 保存

* 另存为

*/

public void Save(){

/**

* 保存文件

*/

if(Util.shell.fileDir!=null ){ //表示该文件有目录,保存时直接保存,不需要弹窗

Util.shell.shell.setText((new File( Util.shell.fileDir.trim())).getName());//获取文件名(不含路径)用于设置title

FileOutputStream fileWriter;

try {

fileWriter = new FileOutputStream(Util.shell.fileDir);

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fileWriter,"gbk"));

out.write(Util.shell.getText().getText());

out.close();

fileWriter.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

else{//否则为从未保存过,则调用另存为窗口

SaveAs();

}

}

public void SaveAs(){

/**

* 将另存为这个方法进行封装,方便调用

*/

FileDialog dialog = new FileDialog(Util.shell.shell,SWT.SAVE);

dialog.setFilterPath(System.getProperty("C:\\Documents and Settings"));//设置打开默认的路径

dialog.setFilterExtensions(new String[]{"*.txt","*.sql","*.java","*.doc"});

String file = dialog.open();//打开窗口,返回用户所选的文件目录

if(file != null){

Util.shell.fileDir = file;//将文件目录保存下来,方面之后的使用

}

if ( file != null )

{

Util.shell.shell.setText((new File( file.trim())).getName());//获取文件名(不含路径)用于设置title

FileOutputStream fileWriter;

try {

fileWriter = new FileOutputStream(file);

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fileWriter,"gbk"));

out.write(Util.shell.getText().getText());

out.close();

fileWriter.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

}

十二、最后我们写一下退出吧,如果你想偷懒的话直接用System.exit(0);也是可以实现这个功能的,但是我觉得吧!这样直接退出不太友好吧!所以我写了下面这种优化的退出方法!

若是保存则说明存在fileDir,直接调用保存的函数即可,若不存在fileDir则说明文件时新打开的,还没确定过路径,因此跳转另存为窗体。

首先定义一个全局变量String fileDir = null;将其赋值为空,默认所有的文件都未保存

接着不管是打开文件,还是另存为文件,都将文件所在目录(包括文件名以及后缀名)记录在fileDir中,最后在保存事件中确定fileDir是否为空即可。

public void quit(){

/**

* 退出函数退出时进行判断是否需要保存

*/

String tips;

if(Util.shell.fileDir != null || Util.shell.getText().getText() != ""){ //文件目录不为空,说明有打开着的文件,需要询问是否保存

if(Util.shell.fileDir == null){

tips = "文件 无标题 的文字已经改变。\n"+"想保存文件吗";

}else{

tips = "文件 " +Util.shell.fileDir + " 的文字已经改变。\n"+"想保存文件吗";

}

int n=JOptionPane.showConfirmDialog(null, tips,"记事本",JOptionPane.YES_NO_CANCEL_OPTION);

if(n==0){ //是 返回0 否返回1 取消 返回2

SaveMethod savemethod = new SaveMethod();

savemethod.Save(); //点是,则保存文件然后打开文件

}else if(n==1){ //返回否

System.exit(0);

}else if(n==2){ //返回取消

return ;

}

System.exit(0);

}else{

if(Util.shell.getText().getText() != ""){ //若目录为空,但是内容不为空,说明有内容但未保存,提示之

tips = "文件 无标题 的文字已经改变!\n"+"想保存文件吗?";

int n=JOptionPane.showConfirmDialog(null, tips,"记事本",JOptionPane.YES_NO_CANCEL_OPTION);

if(n==0){ //是 返回0 否返回1 取消 返回2

SaveMethod savemethod = new SaveMethod();

savemethod.Save(); //点是,则保存文件然后打开文件

}else if(n==1){ //返回否

System.exit(0);

}else if(n==2){ //返回取消

return ;

}

System.exit(0);

}else{

}

}

System.exit(0);

}

写在最后,我们这里还封装了一个弹窗的utils类

public class UiUtils {

/**

* 显示普通对话框的工具类

* @param shell

* @param title

* @param message

*/

public static void showMessageDialog( Shell shell, String title, String message){

MessageBox mb=new MessageBox( shell, SWT.None);

mb.setText(title);

mb.setMessage(message);

mb.open();

}

}总结:技术源于思维,我觉得首先在编程之前还是要有一个整体的想法构思,不要一上来就直接写代码了,首先应该想想你要做什么东西,怎么个做法来实现!对于可重用的代码尽量封装起来,让代码整体看起来更简洁明了。坚持学习,坚持分享!

源码下载地址:点击打开链接http://download.csdn.net/detail/sdksdk0/9501286

java 记事本 新建_java记事本开发相关推荐

  1. java web试题_Java web开发经典面试题汇总(内附答案详解)

    原标题:Java web开发经典面试题汇总(内附答案详解) 1.说出Servlet 的生命周期,并说出Servlet 和CGI 的区别? 答:Web 容器加载Servlet 并将其实例化后,Servl ...

  2. java 记事本 新建_Java 生成一个记事本

    实现打开与保存的记事本 1 packagecom.tanzhou.notepad.util;2 3 importjava.awt.Color;4 importjava.awt.event.Action ...

  3. java 记事本源代码_JAVA记事本源代码 收藏

    JAVA记事本源代码 import java.awt.*; import java.awt.event.*; import java.text.*; import java.util.*; impor ...

  4. java记事本保存_JAVA记事本关于保存

    为什么运行这个程序后点击保存,然后打开时不是按行输出的啊?哪里有问题?publicclassJSBJSB{publicstaticvoidmain(String[]args){FirstWindoww ...

  5. java记事本编译_Java记事本编译

    曹洪胜 2015-05-29 12:13 Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation.保留所有权利. C:\ ...

  6. web开发的java语言步骤_java web开发入门一(servlet和jsp)基于eclispe

    servlet 用java语言开发动态资源网站的技术,在doGet方法中拼接显示html,在doPost方法中提交数据.类似于.net的ashx技术. servlet生成的class文件存放在tomc ...

  7. java系统教程_Java 教程(开发环境配置+基础语法)

    Java 开发环境配置 在本章节中我们将为大家介绍如何搭建Java开发环境. window系统安装java 下载JDK 首先我们需要下载java开发工具包JDK,下载地址:http://www.ora ...

  8. java实践项目_Java项目开发实践

    第章项目开发基础() 项目开发实训目标() 实训知识目标() 实训能力目标() 实训素质目标() 项目开发技术() 图形用户界面编程技术() 输入输出编程技术() 网络编程技术() 数据结构编程技术( ...

  9. java电话计费系统_java 连接数据库开发的电话计费管理系统

    [实例简介] 这是java连接数据库 sql 2000 开发的电话计费管理系统 里面运用的还是比较方便的虽然有一点小问题 [实例截图] [核心代码] 电话计费系统 └── 电话计费系统 ├── all ...

最新文章

  1. 如何成为一个Android高手
  2. iphone桌面横屏设置在哪里_iPhone的实用攻略如此多,这4个你知道吗?
  3. 量子计算机是程序员的未来,研究者:量子计算机一旦成功问世,时间也许会失去存在的意义...
  4. 团队项目计划BACKLOG
  5. java 的类和接口的变量调用
  6. Hinton向AAAI提交论文竟收到最差评价!深度学习三教父再押宝,AI或突破常识瓶颈...
  7. anacodna/python 安装 tensorflow
  8. Python使用for循环打印九九乘法表
  9. 曾经很火的迅雷,为什么现在不怎么火了?
  10. 关于vue-cli中-webkit-flex-direction: column失效问题
  11. spring中afterPropertiesSet方法与init-method配置描述
  12. 最近在写一个IE9的插件
  13. 海思 Hi3559A Sample_vdec视频解码及编译
  14. pyScripter2.7 运行时提示远程解释器再初始化了
  15. 8代cpu装服务器系统,8代cpu不支持win7吗
  16. cad渐开线齿轮轮廓绘制_CAD渐开线齿轮怎么画?
  17. 怎么在网站上设置qq在线客服
  18. iOS之UI--通讯录的实例关键知识技术点积累
  19. Work20230606
  20. Java语言之动画的简单入门学习

热门文章

  1. 科普:什么是编译与反编译
  2. round()函数,四舍五入
  3. 主机插上网线,网卡灯死活不亮
  4. Android 字体粗细的设置
  5. 魅族现在还有root权限吗,魅族完全root权限
  6. springboot 集成 swagger 和knife4j
  7. Pico neo3 Unity打包设置
  8. python中class 类定义与使用
  9. 老主板也能支持新APU:七彩虹更新5款主板BIOS
  10. vue 详情页返回列表,过滤查询条件保留