zoukankan      html  css  js  c++  java
  • java记事本开发

    今天我想要分享的是一个用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("u67E5u627E");
    		
    		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("u67E5u627Eu4E0Bu4E00u5904(F)");
    		
    		Label lblNewLabel = new Label(shell, SWT.NONE);
    		lblNewLabel.setBounds(10, 10, 85, 22);
    		lblNewLabel.setText("u67E5u627Eu5185u5BB9(&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("u53D6u6D88");
    		
    		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("u533Au5206u5927u5C0Fu5199(&C)");
    		
    		Label label1 = new Label(shell, SWT.NONE);
    		label1.setText("u66FFu6362u4E3A(&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("u66FFu6362(&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 = "文件  无标题   的文字已经改变。
    "+"想保存文件吗";
    			}else{
    				tips = "文件  " +Util.shell.fileDir + "  的文字已经改变。
    "+"想保存文件吗";
    			}
    			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 = "文件  无标题   的文字已经改变!
    "+"想保存文件吗?";
    				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




  • 相关阅读:
    网页制作-表单元素2
    网页制作-表单元素
    网页制作_表格
    网页制作常用标签
    IT新起之秀
    Android Studio 快捷键
    android github
    手机抓包 http tcp udp?
    Ubuntu16.04 Caffe 安装步骤记录(超详尽)(转载)
    ubuntu16.04 在cuda9.0环境下编译安装opencv2.4.13.7
  • 原文地址:https://www.cnblogs.com/sdksdk0/p/5585058.html
Copyright © 2011-2022 走看看