JAVA/GUI程序之记事本
Posted 追求沉默者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA/GUI程序之记事本相关的知识,希望对你有一定的参考价值。
自上半年JAVA课程结束后,再也没有看过JAVA了,最近不是很忙,又简单的看了看,本博客纯属记录学习过程,请大神们别笑,其中错误是难免的,毕竟是新手写的博客。下面就进入我们的正题吧,复习GUI时,就想到WINDOWS的记事本,如果用GUI来仿写应该不难。实现向记事本这样的文本编辑器,第一步,当然是界面的问题,这对于GUI来说再简单不过了,所以我也不多说了,直接贴上代码即可,相信都能看懂。
创建菜单代码:
1 //创建主菜单 2 public void createMenu() 3 { 4 //创建JMenuBar菜单条 5 mainMenuBar=new JMenuBar(); 6 //创建四个JMenu下拉菜单 7 fileMenu=new JMenu("文件(F)"); 8 editMenu=new JMenu("编辑(E)"); 9 formatMenu=new JMenu("格式(O)"); 10 viewMenu=new JMenu("查看(V)"); 11 helpMenu=new JMenu("帮助(H)"); 12 //创建JMenuItem并添加到对应的JMenu中 13 mainMenuBar.add(fileMenu); 14 newItem=new JMenuItem("新建"); 15 openItem=new JMenuItem("打开.."); 16 saveItem=new JMenuItem("保存.."); 17 saveasItem=new JMenuItem("另存为.."); 18 pageItem=new JMenuItem("页面设置.."); 19 printItem=new JMenuItem("打印.."); 20 exitItem=new JMenuItem("退出"); 21 fileMenu.add(newItem); 22 fileMenu.add(openItem); 23 fileMenu.add(saveItem); 24 fileMenu.add(saveasItem); 25 fileMenu.addSeparator(); 26 fileMenu.add(pageItem); 27 fileMenu.add(printItem); 28 fileMenu.addSeparator(); 29 fileMenu.add(exitItem); 30 31 mainMenuBar.add(editMenu); 32 undoItem=new JMenuItem("撤消"); 33 cutItem=new JMenuItem("剪切"); 34 copyItem=new JMenuItem("复制"); 35 pasteItem=new JMenuItem("粘贴"); 36 findItem=new JMenuItem("查找.."); 37 replaceItem=new JMenuItem("替换.."); 38 selectallItem=new JMenuItem("全选"); 39 dateItem=new JMenuItem("时间/日期"); 40 editMenu.add(undoItem); 41 editMenu.addSeparator(); 42 editMenu.add(cutItem); 43 editMenu.add(copyItem); 44 editMenu.add(pasteItem); 45 editMenu.addSeparator(); 46 editMenu.add(findItem); 47 editMenu.add(replaceItem); 48 editMenu.addSeparator(); 49 editMenu.add(selectallItem); 50 editMenu.add(dateItem); 51 mainMenuBar.add(formatMenu); 52 wrapItem=new JCheckBoxMenuItem("自动换行"); 53 fontItem=new JMenuItem("设置字体.."); 54 formatMenu.add(wrapItem); 55 formatMenu.add(fontItem); 56 mainMenuBar.add(viewMenu); 57 mainMenuBar.add(helpMenu); 58 helpItem=new JMenuItem("查看帮助(H)"); 59 aboutItem=new JMenuItem("关于记事本..(A)"); 60 helpMenu.add(helpItem); 61 helpMenu.add(aboutItem); 62 //为每个菜单项添加监听器 63 exitItem.addActionListener(this); 64 saveItem.addActionListener(this); 65 saveasItem.addActionListener(this); 66 newItem.addActionListener(this); 67 printItem.addActionListener(this); 68 openItem.addActionListener(this); 69 cutItem.addActionListener(this); 70 copyItem.addActionListener(this); 71 pasteItem.addActionListener(this); 72 selectallItem.addActionListener(this); 73 dateItem.addActionListener(this); 74 wrapItem.addActionListener(this); 75 findItem.addActionListener(this); 76 fontItem.addActionListener(this); 77 helpItem.addActionListener(this); 78 aboutItem.addActionListener(this); 79 }
下面继续看看每个菜单的具体响应和实现。
1."新建"功能的实现:
当使用者点击“新建”菜单时,首先要判断文件中的内容是否改变过,如果修改过,则询问使用者是否要保存修改,并且根据选择做出相应的动作,如果用户选择“是“,则保存修改后的文件,否则保存原来的文档。具体代码如下:
1 void doNewFile() 2 { 3 int select,flag; 4 if (changed)//判断文件内容是否修改过 5 { 6 select=JOptionPane.showConfirmDialog(this,"文件修改后尚未存盘,要保存吗?"); 7 switch (select) 8 { 9 case JOptionPane.YES_OPTION: 10 flag=doSave(); 11 break; 12 case JOptionPane.NO_OPTION: 13 flag=1; 14 break; 15 default: 16 flag=0; 17 break; 18 } 19 } 20 else 21 { 22 flag = 1; 23 } 24 if(flag==1)//新建文件,并设置内容为空 25 { 26 changed=false; 27 haveName=false; 28 setTitle("无名称——记事本"); 29 text.setText(null); 30 } 31 }
2.“打开”功能的实现:
当用户选择“打开”菜单时,首先判断文件内容是否修改过,若修改过,则询问是否保存,若用户选择“是”,则弹出保存窗口,否则弹出一个文件选择对话框由使用者选择要打开的文件,并且读入选择的文件的内容并复制给text。具体代码如下:
1 void doOpenFile() 2 { 3 int select,flag; 4 File tmpfile=null; 5 ExampleFileFilter filter; 6 JFileChooser chooser; 7 FileInputStream fin; 8 byte buf[]; 9 //判断文件内容是否修改过并询问是否存盘 10 if (changed) 11 { 12 select=JOptionPane.showConfirmDialog(this,"文件已修改,是否要保存?"); 13 switch (select) 14 { 15 case JOptionPane.YES_OPTION: 16 flag=doSave(); 17 break; 18 case JOptionPane.NO_OPTION: 19 flag=1; 20 break; 21 default: 22 flag=0; 23 break; 24 } 25 } 26 else 27 { 28 flag = 1; 29 } 30 //当前文件处理完毕,准备打开一个文件 31 if(flag==1) 32 { 33 changed = false; 34 //设置文件类型过滤器 35 filter = new ExampleFileFilter(); 36 filter.addExtension("txt"); 37 filter.setDescription("文本文件"); 38 //模拟记事本设置默认打开路径 39 if (file!=null) 40 chooser = new JFileChooser(file.getPath()); 41 else 42 chooser = new JFileChooser(); 43 chooser.setFileFilter(filter); 44 select = chooser.showOpenDialog(this); 45 if(select == JFileChooser.APPROVE_OPTION) 46 { 47 tmpfile=chooser.getSelectedFile();//使用文件流读入文件类容 48 try 49 { 50 fin=new FileInputStream(tmpfile); 51 buf=new byte[(int)tmpfile.length()]; 52 fin.read(buf); 53 fin.close(); 54 text.setText(new String(buf));//实现内容的现实 55 changed=false; 56 haveName=true; 57 file=tmpfile; 58 setTitle("记事本 -- "+file.getName()); 59 }catch(FileNotFoundException e) 60 { 61 JOptionPane.showMessageDialog(this,"指定的文件名称或属性有问题!"); 62 }catch(IOException e) 63 { 64 JOptionPane.showMessageDialog(this,"无法读文件,请检查文件是否被锁定"); 65 } 66 } 67 } 68 }
运行截图:
3.保存功能的实现:
当使用者点击“保存”菜单时,需要完成如下事情:第一、判断文件是否为新建的文件,如果是,则调用doSaveAs()来保存;否则,判断原文件内容是否发生修改,若修改过,再询问用户是否另存,否则不做任何动作。具体代码如下:
1 //保存使用者编辑的文件,保存成功返回1,否则返回0 2 int doSave() 3 { 4 FileOutputStream fout; 5 byte content[]; 6 int flag; 7 if (!haveName)//判断是否新建的文件 8 { 9 flag = doSaveAs(); 10 } 11 else if(changed)//判断内容是否发生修改 12 { 13 try 14 { 15 fout=new FileOutputStream(file); 16 content=text.getText().getBytes(); 17 fout.write(content); 18 fout.close(); 19 changed=false; 20 flag = 1; 21 }catch(FileNotFoundException e)//进行相应异常处理 22 { 23 JOptionPane.showMessageDialog(this,"指定的文件名称或属性有问题!"); 24 flag = 0; 25 }catch(IOException e) 26 { 27 JOptionPane.showMessageDialog(this,"无法写文件,请检查文件是否被锁定"); 28 flag = 0; 29 } 30 } 31 else 32 { 33 flag =1; 34 } 35 return flag; 36 }
4.实现“另保存”功能:
当使用者选择“另存为”菜单时,打开一个保存对话框,让使用者选择保存路径和文件名,如果文件名已存在,则弹出一个警告框,让使用者选择是否覆盖文件。否则以用户填写的文件名来保存文件并更改相关变量。
为了实现这些功能,需要用到JFileChooser类和ExampleFileFilter类。而ExampleFileFilter类并不是JAVA标准库的类,所以必须将它引入的项目中,有关于相关的配置就不介绍了,网上有很多资料。同时,由于要处理用户的输入,因此需要大量的代码来提高容错率即程序的健壮性。具体代码如下:
1 //用"另存为"对话框保存文件。保存成功返回1,否则返回0 2 int doSaveAs() 3 { 4 FileOutputStream fout; 5 byte content[]; 6 int flag=0; 7 File tmpfile=null; 8 ExampleFileFilter filter = new ExampleFileFilter(); 9 JFileChooser chooser; 10 filter.addExtension("txt");//设置保存文件对话框中的文件属性过滤器 11 filter.setDescription("文本文件"); 12 if (file!=null) 13 chooser = new JFileChooser(file.getPath()); 14 else 15 chooser = new JFileChooser(); 16 chooser.setFileFilter(filter);//设置文件类型 17 flag = chooser.showSaveDialog(this); 18 if(flag == JFileChooser.APPROVE_OPTION) 19 { 20 tmpfile=chooser.getSelectedFile(); 21 if (tmpfile.exists())//判断同名同类文件是否已存在 22 { 23 if (JOptionPane.showConfirmDialog(this,"文件已经存在,是否覆盖?", 24 "警告",JOptionPane.YES_NO_OPTION)==JOptionPane.YES_OPTION) 25 { 26 flag=1; 27 } 28 else 29 { 30 flag=0; 31 } 32 } 33 else 34 { 35 flag=1; 36 } 37 } 38 else 39 { 40 flag=0; 41 } 42 43 if (flag==1) 44 {//用户已经确定要以指定名称保存文件 45 try 46 { 47 fout=new FileOutputStream(tmpfile); 48 content=text.getText().getBytes(); 49 fout.write(content); 50 fout.close(); 51 flag = 1; 52 }catch(FileNotFoundException e) 53 { 54 JOptionPane.showMessageDialog(this,"指定的文件名称或属性有问题!"); 55 flag = 0; 56 }catch(IOException e) 57 { 58 JOptionPane.showMessageDialog(this,"无法写文件,请检查文件是否被锁定"); 59 flag = 0; 60 } 61 } 62 63 if (flag==1) 64 {//文件保存成功,修改相关变量 65 changed=false; 66 haveName=true; 67 file=tmpfile; 68 this.setTitle(file.getName()+"——记事本"); 69 } 70 return flag; 71 }
5.“打印”菜单功能的相应:
JAVA中关于打印API主要存在于java.awt.print包中,但是,在此我们使用JDK1.4新增的javax.print包和其相应子包javax.print.event和javax.print.attribute中的类来实现打印功能。其中,javax.print包中的主要包括打印服务的相关类,而javax.print.evevt则包含打印事件的相关定义,javax.print.attribute则包括打印服务的可用属性列表等。
要实现打印功能,步骤如下:
- 定位到一台打印机
- 指定要打印的格式
- 设置打印属性
- 设置打印内容
- 开始打印
具体代码如下:
1 //调用打印对话框,给用户打印文档 2 void doPrint() 3 { 4 try{ 5 //构建打印属性集 6 PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet(); 7 //设置打印格式 8 DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE; 9 //查找所有的可用打印服务 10 PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor, pras); 11 PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService(); 12 //显示打印对话框 13 PrintService service = null; 14 service = ServiceUI.printDialog(null, 100, 100, printService, defaultService, flavor, pras); 15 if (service!=null)// 16 { 17 //创建打印作业 18 DocPrintJob job = service.createPrintJob(); 19 DocAttributeSet das = new HashDocAttributeSet(); 20 //建立打印文件格式 21 Doc doc = new SimpleDoc(text.getText().getBytes(), flavor, das); 22 //进行文件的打印 23 job.print(doc, pras); 24 } 25 }catch(Exception e) 26 { 27 JOptionPane.showMessageDialog(this,"打印任务无法完成"); 28 } 29 }
6."退出功能的实现"
关于这个功能比较简单,但是需要注意一个问题,当点击窗体右上不得关闭按钮时,也需要作出相应的响应,而不是直接退出,因此,在程序中需要覆盖JFrame的窗口关闭方法processWindowEvent(注意:这里不是监听windowsClosing事件)。具体代码如下:
protected void processWindowEvent(WindowEvent e) { if (e.getID() == WindowEvent.WINDOW_CLOSING) doExit(); }
//程序退出时的代码 void doExit() { int select; if (!changed) //判断文件是否发生改变 System.exit(0); else { select=JOptionPane.showConfirmDialog(this,"文件修改后尚未存盘,要保存吗?"); switch (select) { case JOptionPane.YES_OPTION: select=doSave(); if (select==1)System.exit(0); break; case JOptionPane.NO_OPTION: System.exit(0); break; case JOptionPane.CANCEL_OPTION: break; } } }
7.“剪切”功能的实现:
为了完成这一功能,应该为文本框添加两个监听器:键盘事件监听器KeyListener和鼠标事件监听器MouseListener。并且实现其中的keyPressed和mouseRealseed方法就可以了。这里我们采用继承相应的适配器类KeyAdapter和MouseAdapter即可。这部分相当简单,就不多说了。下面是具体代码:
//监听鼠标事件 class handleMouse extends MouseAdapter { public void mouseReleased(MouseEvent e) { chkText(); } } //监听键盘事件 class handleKey extends KeyAdapter { public void keyPressed(KeyEvent e) { chkText(); } } //根据用户选择文本的情况,修改菜单的状态 void chkText() { if(text.getSelectedText()==null) { cutItem.setEnabled(false); copyItem.setEnabled(false); } else { cutItem.setEnabled(true); copyItem.setEnabled(true); } } //将用户选择的文本剪切到剪贴板 void doCut(){ text.cut(); }
8.实现查找功能:
由于该部分功能JDK并没有提供查找对话框,我就模仿Windows的记事本啦。代码如下:
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 public class findDialog extends JDialog implements ActionListener 6 { 7 Container con; 8 JPanel panel1,panel2; 9 JTextArea text; 10 JLabel label1; 11 JTextField findEdit; 12 JCheckBox checkBox; 13 JRadioButton upBtn,downBtn; 14 ButtonGroup dirBtnGroup; 15 JButton OKBtn,CancleBtn; 16 17 int start; 18 public findDialog(JFrame owner, JTextArea Jtext) 19 { 20 super(owner,false); 21 start=0; 22 text=Jtext; 23 panel1=new JPanel(); 24 panel1.setLayout(new FlowLayout()); 25 panel2=new JPanel(); 26 panel2.setLayout(new FlowLayout()); 27 28 label1=new JLabel("查找内容"); 29 findEdit=new JTextField(12); 30 OKBtn=new JButton("查找下一个"); 31 OKBtn.addActionListener(java学习 之 第一个程序及认识