JAVA模拟win7记事本

 使用JAVA模拟记事本

学校老师叫用java swing写一个记事本,虽然java窗体不是java的强项,但还是可以作为练习熟悉一下的。

因为记事本这种单一的小东西,所以不需要什么耦合不需要太低,虽然背离了低耦合,但是写起来是相当方便

按win7模拟出来的记事本。

大体把所需类分为如下:

1,文本域创建与功能

2,编辑菜单功能

3,文件菜单功能

3,格式菜单功能

4,帮助菜单功能

5,查看菜单功能

6,总菜单

7,主函数(主界面)

8,系统剪切板工具

9,状态栏

10,界面设置

 

界面参考如下

下面进入正式代码分析(使用部分代码分析,具体代码后面用链接给出):

1,文件

需要一个保存路径的变量,然后文本域里也需要有一个变量判断是否被修改过

新建:

这里需要判断文件是否被修改过,如果有,询问用户是否保存,然后再操作,如果没有,直接清空文本域类容与清空保存的路径

if (CreateText.isChangeT()) {
			int change = JOptionPane.showConfirmDialog(null, "是否将保存更改", "记事本",
					0);
			switch (change) {
			case JOptionPane.YES_NO_OPTION:
				if (textpath == null) {
					FileTool.setSave("保存");
				} else {
					FileTool.setPreserve();
				}
				CreateText.getJTexts().setText("");
				textpath = null;
				CreateText.setChangeT(false);
				break;
			case JOptionPane.CLOSED_OPTION:
				break;
			case JOptionPane.NO_OPTION:
				CreateText.getJTexts().setText("");
				textpath = null;
				CreateText.setChangeT(false);
				break;
			default:

				break;
			}

		} else {
			CreateText.getJTexts().setText("");
			textpath = null;
			CreateText.setChangeT(false);
		}

 

打开:

 

就是一个流,但是要先判断文本域里的类容是否被修改过,如果有,就询问用户是否保存,然后再实现用文件选择器选择路径读取的操作,打开后,要把打开的路径替换原来的保存路径,然后文本是否修改改为否

JFileChooser jfc = new JFileChooser(".");
		FileFilter ff = new FileNameExtensionFilter("文本文档(*.txt)", "txt");
		jfc.setAcceptAllFileFilterUsed(false);
		jfc.setFileFilter(ff);
		if (jfc.showDialog(null, null) == 0) {
			CreateText.getJTexts().setText("");
			textpath = jfc.getSelectedFile().getAbsolutePath();

			Notepad.getJf().setTitle(textpath);

			try {
				InputStream input = new BufferedInputStream(
						new FileInputStream(textpath));

				byte[] by = new byte[1024];
				int len = input.read(by);
				while (len != -1) {
					CreateText.getJTexts().append(
							new String(by, 0, len));
					len = input.read(by);
				}

				input.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		CreateText.setChangeT(false);

保存与另存为:

另存为多实现一个重新选择路径存储,这个存储不替换保存的路径。

保存就是直接安已经保存的路径存储,如果没有保存的路径,就打开路径选择器选择一个路径,下面提供保存的代码(使用的缓冲流)

StringBuffer str = new StringBuffer();

		try {
			OutputStream out = new BufferedOutputStream(new FileOutputStream(
					textpath));
			
			String[] lines = CreateText.getJTexts().getText().split("\n");
			for(int i = 0;i < lines.length;i++)
			{
				System.out.println(lines[i]);
				str.append(lines[i] + "\r\n");
			}			

			out.write(str.toString().getBytes("utf-8"));
			out.close();
			CreateText.setChangeT(false);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

页面设置与打印:

由于不好测试,就实现了一个java自带的打印机。

页面设置也刚好带入在里面,页面设置使用Robot实现模拟快捷键跳转到页面设置里(暂时没想到好的办法,这种方法也有个小bug,有可能切换失败,可以额外用一个线程,在几十毫秒后再使用虚拟按键,效果应该会好很多)<—欢迎大神提出意见

	private static final void setPrintf(boolean whether) {
		
		PrinterJob print = PrinterJob.getPrinterJob();
		HashPrintRequestAttributeSet attr = new HashPrintRequestAttributeSet();
		if(whether)
		{
			Robot robot = null;
			try {  
		            robot = new Robot();//创建Robot对象  
		        } catch (Exception e) {  
		            // TODO Auto-generated catch block  
		            e.printStackTrace();  
		        }
			robot.keyPress(KeyEvent.VK_ALT);
			robot.keyPress(KeyEvent.VK_S);
			robot.keyRelease(KeyEvent.VK_S);
			robot.keyRelease(KeyEvent.VK_ALT);
			
		}
		
		print.printDialog(attr);
	}

退出:

这个就不用说了,再询问用户是否保存后,直接System.exit(0)

 

2,编辑

文本域发生改变时判断是否可用,撤销的稍稍特殊下面再说,剪切,复制,删除是要选中的东西有类容才能可用

撤销:

使用UndoManager实现,关联文本域后,用canUndo()方法来看是否可以撤销,如果可以,就把撤销变为可用,撤销的方法是undo()

 

剪切,复制,粘贴,删除:

前三个文本域自带有方法,在有文字被选中后,这几个变为可用,然后分别用cut(),copy(),paste()方法来实现前三个,

删除操作由于没有自带的方法,就用Robot来模拟Delete键

下面提供,这四个选项,啥时候可用与不可用的事件方法

jta.addCaretListener(new CaretListener() {
			// 文本框类容变动事件
			@Override
			public void caretUpdate(CaretEvent arg0) {
				// TODO Auto-generated method stub

				getsetPosition();
				if (undomg.canUndo()) {
					MenuBar.getBjs(0).setEnabled(true);
				} else {
					MenuBar.getBjs(0).setEnabled(false);
				}

				if (ShearPlate.getCbt() != null) {
					MenuBar.getBjs(3).setEnabled(true);
				} else {
					MenuBar.getBjs(3).setEnabled(false);
				}
				
				if(!"".equals(jta.getText()))
				{
					MenuBar.getBjs(5).setEnabled(true);
					MenuBar.getBjs(6).setEnabled(true);
				}
				else
				{
					MenuBar.getBjs(5).setEnabled(false);
					MenuBar.getBjs(6).setEnabled(false);
				}

				if (jta.getSelectedText() != null) {
					MenuBar.getBjs(1).setEnabled(true);
					MenuBar.getBjs(2).setEnabled(true);
					MenuBar.getBjs(4).setEnabled(true);
					
				} else {
					MenuBar.getBjs(1).setEnabled(false);
					MenuBar.getBjs(2).setEnabled(false);
					MenuBar.getBjs(4).setEnabled(false);
					
				}
			}
		});

 

查询,查找下一个,替换:

这几个都是息息相关的,创建两个对话框,其中一个是查询的,一个是查找下一个,一个是替换

查找与替换都是根据光标所在位置来操作,其中替换的操作是需要选中字符来执行替换

下面是两个窗体预览

里面有类容时,这两个选项才可用,当查找类容有类容时按钮才可用,然后就是对文本域里的类容一系列操作,光标定位,然后由光标向上,向下查找,选中查找的类容,替换的时候就替换选中的类容,区分大小写这些,也是字符串的操作之一,记不起来查查API就有了,下面提供查询的代码,,替换就用replace实现,代码差异不大,代码太多,不一一展示。

String strb = CreateText.getJTexts().getText();

		int len = CreateText.getJTexts().getCaretPosition();
		int max = CreateText.getJTexts().getText().length();
		String str;
		int ch;
		String rep = reps;
		if (upandfl) {
			rep = rep.toLowerCase();
			strb = strb.toLowerCase();
		}
		if (lefrig) {
			str = strb.substring(len, max);
			ch = str.indexOf(rep);
		} else {
			str = strb.substring(0, len - 1);
			ch = str.lastIndexOf(rep);
		}

		int scope = rep.length();

		if (ch >= 0 && ch < max) {
			if (lefrig)
				CreateText.getJTexts().select(len + ch, len + ch + scope);
			else
				CreateText.getJTexts().select(ch, ch + scope);

		} else {
			JOptionPane.showConfirmDialog(null, "未找到" + reps, "记事本", 0);
		}

转到与全选:

转到我没写,所以我禁用了这个选项,转到的实现思想就是,当有类容时,变为可用,再把光标定位到所输入的行数

全选文本域自带有方法selectAll()

 

时间/日期

获取当前日期,格式化字符串后追加到文本域里就行,追加是默认追加到光标位置的(又能偷懒一串代码)

	public static final String getDate() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd- HH:mm ");
		Date date = new Date();
		String str = sdf.format(date) + String.format("%tA", date);
		return str;

	}

 

 

3,格式

自动换行,文本域有自带的,当自动换行时,取消横向的滚动条,取消状态栏禁用查看里的状态栏显示

字体需要引入本机有的字体名,由于java的swing组价支持html4与css2,所以选择框样式很是方便了

1,自动换行

直接给代码,没啥需要注意的,就是对窗体的改变与禁用隔壁查看的状态栏显示

MenuBar.getGss(0).addActionListener(new ActionListener() {
			// 自动换行功能
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				if (!CreateText.getJTexts().getLineWrap()) {
					
					CreateText.getJTexts().setLineWrap(true);
					StatusBar.getStatusJp().setVisible(false);
					MenuBar.getCks().setEnabled(false);
					CreateText.getJsp().setHorizontalScrollBarPolicy(
							JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
				} else {
					
					CreateText.getJTexts().setLineWrap(false);
					StatusBar.getStatusJp().setVisible(true);
					MenuBar.getCks().setEnabled(true);
					CreateText.getJsp().setHorizontalScrollBarPolicy(
							JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
				}

			}
		});

2,字体

先预览

读取电脑里的字体的文件名,也只需要文件名

GraphicsEnvironment fonts = GraphicsEnvironment
				.getLocalGraphicsEnvironment();
		String[] strfile = fonts.getAvailableFontFamilyNames();

存储后放到JList里,在把JList放到滚动面板里,当用户选择类容后,就把类容放置到上面的框里,其他三个框也是相同操作

		
		for(int i = 0;i < strfile.length;i++)strfile[i] = "<html><font face=\""+strfile[i] + "\">"+strfile[i]+"</font></html>";

		final JList jliw = new JList(strfile);
		jliw.addListSelectionListener(new ListSelectionListener() {

			@Override
			public void valueChanged(ListSelectionEvent arg0) {
				// TODO Auto-generated method stub
				jtf[0].setText(clearHtml((String) jliw.getSelectedValue()));
				
				jlcs.setFont(new Font((String) jtf[0].getText(),
						map.get(jtf[1].getText()), Integer.parseInt(jtf[2].getText())));
			}
		});
		jliw.setFont(new Font("微软雅黑", Font.PLAIN, 14));
		jspw.setViewportView(jliw);
		jspw.setBounds(10, 70, 260, 200);

最后到确定的时候,就改变文本域里的字体,字形,字号(预先要有三个变量存储这三个值),下次点开的时候,三个文本框里默认要显示这三个值。

		confirm.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub

				MyFont = jtf[0].getText();
				Fontset = jtf[1].getText();
				MyfontSize = jtf[2].getText();

				CreateText.getJTexts().setFont(
						new Font(MyFont, map.get(Fontset), Integer
								.parseInt(MyfontSize)));
				jd.dispose();
			}
		});

 

4,查看

查看里就只有可怜的一个状态栏是否显示(还有可能被隔壁的自动换行禁用),单击他,判断状态栏是否显示,显示则隐藏,隐藏则显示

MenuBar.getCks().addActionListener(new ActionListener() {
			// 状态栏事件
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				if (StatusBar.getStatusJp().isVisible()) {
					StatusBar.getStatusJp().setVisible(false);
				} else {
					StatusBar.getStatusJp().setVisible(true);
				}
			}
		});

5,帮助

这个就不说了。。写两个小提示框就成,我的查看帮助没写,感觉没必要,关于记事本倒是写了一个,下面是效果,附带一个文本域字体,字形,字号改变

 

不怎么用java的窗体操作,感觉java强大的地方在于web和安卓,不过这个东西很练手,对字符串操作的掌控,参数的传递,对代码全局的掌控,也需要点小小的逻辑(其实这是作业,顺便发表一下)

 

代码不足之处,欢迎指教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值