《记事本》第2节:记事本功能实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《记事本》第2节:记事本功能实现相关的知识,希望对你有一定的参考价值。

​记事本有很多功能,本小节将讲解其中较为重要的功能的实现过程。

22.2.1初始化菜单

记事本界面上最多的就是菜单和菜单项。如果在窗体上添加菜单,先要添加一个菜单栏。在Swing体系中,用JMenuBar类表示菜单栏,创建菜单栏的语句如下:​

JMenuBar mainMenuBar=new JMenuBar();

创建菜单栏、给菜单栏添加菜单、给菜单添加菜单项以及给菜单项添加监听器的操作全部集中在createMenu()方法中实现,而createMenu()方法又在专门初始化组件的init()方法中被调用,以下是createMenu()方法的实现过程。​

public void createMenu()
//创建JMenuBar
mainMenuBar=new JMenuBar();
//创建四个JMenu
fileMenu=new JMenu("文件");
editMenu=new JMenu("编辑");
formatMenu=new JMenu("格式");
helpMenu=new JMenu("帮助");
//创建JMenuItem并添加到对应的JMenu中
mainMenuBar.add(fileMenu);
newItem=new JMenuItem("新建");
openItem=new JMenuItem("打开..");
saveItem=new JMenuItem("保存..");
saveasItem=new JMenuItem("另存为..");
pageItem=new JMenuItem("页面设置..");
printItem=new JMenuItem("打印..");
exitItem=new JMenuItem("退出");
fileMenu.add(newItem);
fileMenu.add(openItem);
fileMenu.add(saveItem);
fileMenu.add(saveasItem);
fileMenu.addSeparator();
fileMenu.add(pageItem);
fileMenu.add(printItem);
fileMenu.addSeparator();
fileMenu.add(exitItem);
mainMenuBar.add(editMenu);
undoItem=new JMenuItem("撤消");
cutItem=new JMenuItem("剪切");
copyItem=new JMenuItem("复制");
pasteItem=new JMenuItem("粘贴");
findItem=new JMenuItem("查找..");
replaceItem=new JMenuItem("替换..");
selectallItem=new JMenuItem("全选");
dateItem=new JMenuItem("时间/日期");
editMenu.add(undoItem);
editMenu.addSeparator();
editMenu.add(cutItem);
editMenu.add(copyItem);
editMenu.add(pasteItem);
editMenu.addSeparator();
editMenu.add(findItem);
editMenu.add(replaceItem);
editMenu.addSeparator();
editMenu.add(selectallItem);
editMenu.add(dateItem);

mainMenuBar.add(formatMenu);
wrapItem=new JCheckBoxMenuItem("自动换行");
fontItem=new JMenuItem("设置字体..");
formatMenu.add(wrapItem);
formatMenu.add(fontItem);
mainMenuBar.add(helpMenu);
helpItem=new JMenuItem("帮助主题");
aboutItem=new JMenuItem("关于..");
helpMenu.add(helpItem);
helpMenu.add(aboutItem);
//给菜单项添加监听器
exitItem.addActionListener(listener);
saveItem.addActionListener(listener);
saveasItem.addActionListener(listener);
newItem.addActionListener(listener);
printItem.addActionListener(listener);
openItem.addActionListener(listener);
cutItem.addActionListener(listener);
copyItem.addActionListener(listener);
pasteItem.addActionListener(listener);
selectallItem.addActionListener(listener);
dateItem.addActionListener(listener);
wrapItem.addActionListener(listener);
findItem.addActionListener(listener);
fontItem.addActionListener(listener);

22.2.2保存功能

当用户单击“保存”菜单项时,程序必须完成以下操作:​

  • 判断文件是否为新文件,如果是新文件调用doSaveAs()方法实现保存操作。​
  • 如果不是新文件,查看上次保存之后是否有过修改操作,如果有修改操作直接以原文件名保存,否则调用doSaveAs()方法进行保存。​
  • 如果没有任何修改,则不需要做任何操作。​

与保存相关的操作基本都由doSaveAs()方法完成的,doSaveAs()方法的实现过程如下:​

int doSaveAs()
FileOutputStream fout;
byte content[];
int flag=0;
File tmpfile=null;
ExampleFileFilter filter = new ExampleFileFilter();
JFileChooser chooser;
filter.addExtension("txt");
filter.setDescription("文本文件");
if (file!=null)
chooser = new JFileChooser(file.getPath());

else
chooser = new JFileChooser();

chooser.setFileFilter(filter);
flag = chooser.showSaveDialog(this);
if(flag == JFileChooser.APPROVE_OPTION)
tmpfile=chooser.getSelectedFile();
if (tmpfile.exists())
if (JOptionPane.showConfirmDialog(this,"文件已经存在,是否覆盖?",
"警告",
JOptionPane.YES_NO_OPTION)==JOptionPane.YES_OPTION)
flag=1;
else
flag=0;

else
flag=1;

else
flag=0;


if (flag==1)//用户已经确定要以指定名称保存文件
try
fout=new FileOutputStream(tmpfile);
content=text.getText().getBytes();
fout.write(content);
fout.close();
flag = 1;
catch(FileNotFoundException e)
JOptionPane.showMessageDialog(this,"指定的文件名称或属性有问题!");
flag = 0;
catch(IOException e)
JOptionPane.showMessageDialog(this,"无法写文件,请检查文件是否被锁定");
flag = 0;



if (flag==1)//文件保存成功,修改相关变量
changed=false;
haveName=true;
file=tmpfile;
this.setTitle("记事本 -- "+file.getName());

return flag;

22.2.3打开功能

当用户单击“打开”菜单项时,程序应完成以下操作:​

  • 判断当前文件是否被修改过,如果修改过则询问用户是否要保存当前文件。​
  • 如果用户选择“取消”则关闭对话框,否则弹出文件选择对话框由用户选择要打开的文件。​
  • 读入用户选择的文件内容,并把这些内容显示到窗体的文本区text中。​

打开操作主要调用doOpen()方法完成,其实现过程如下:​

//打开一个已经存在的文件
void doOpen()
int select,flag;
File tmpfile=null;
ExampleFileFilter filter;
JFileChooser chooser;
FileInputStream fin;
byte buf[];
if (changed)
select=JOptionPane.showConfirmDialog(this,"文件修改后尚未存盘,要保存吗?");
switch (select)
case JOptionPane.YES_OPTION:
flag=doSave();
break;
case JOptionPane.NO_OPTION:
flag=1;
break;
default:
flag=0;
break;

else
flag = 1;

if(flag==1)
changed = false;
filter = new ExampleFileFilter();
filter.addExtension("txt");
filter.setDescription("文本文件");
if (file!=null)
chooser = new JFileChooser(file.getPath());

else
chooser = new JFileChooser();

chooser.setFileFilter(filter);
select = chooser.showOpenDialog(this);
if(select == JFileChooser.APPROVE_OPTION)
tmpfile=chooser.getSelectedFile();
try
fin=new FileInputStream(tmpfile);
buf=new byte[(int)tmpfile.length()];
fin.read(buf);
fin.close();
text.setText(new String(buf));
changed=false;
haveName=true;
file=tmpfile;
setTitle("记事本 -- "+file.getName());
catch(FileNotFoundException e)
JOptionPane.showMessageDialog(this,"指定的文件名称或属性有问题!");
catch(IOException e)
JOptionPane.showMessageDialog(this,"无法读文件,请检查文件是否被锁定");



22.2.4全选、剪切、复制和粘贴文本

一般情况下,用户如果没有选择文本,那么剪切和复制菜单项应处于不可用状态,而一旦用户选择了一段文本,则这两个菜单项就应该立刻变成可用状态。​

为实现这种效果,应该为文本区添加两个监听器,分别是键盘监听器和鼠标监听器。在本案例的程序代码中以适配器类的子类作为监听器的实现类,并且这两个监听器类被定义为内部类。这两个监听器主要监听文档是否发生了修改,其实现过程如下:

//键盘监听器类
class HandleKey extends KeyAdapter
public void keyPressed(KeyEvent e)
chkText();


//鼠标监听器类
class HandleMouse extends MouseAdapter
public void mouseReleased(MouseEvent e)
chkText();


//根据用户选择文本的情况,修改菜单的状态
void chkText()
if (text.getSelectedText() == null)
cutItem.setEnabled(false);
copyItem.setEnabled(false);
else
cutItem.setEnabled(true);
copyItem.setEnabled(true);

全选功能由doSelectAll()方法实现,其代码如下:​

//全选​
void doSelectAll()
text.selectAll();

有了前面的准备工作,复制文本变得很简单,只需要调用doCopy()方法就能实现,其代码如下:​

//将用户选择的文本复制到剪贴板​
void doCopy()
text.copy();

同样的,实现剪切操作也很简单,只需要调用doCut()方法就能实现,其代码如下:​

//将用户选择的文本复制到剪贴板​
void doCut()
text.cut();

粘贴功能由doPaste()方法实现,其代码如下:​

//将剪贴板中的内容复制到文本区​
void doPaste()
text.paste();

22.2.5打印功能

Java的打印API主要存在于java.awt.print包下,而JDK1.4新增的与打印相关的类则在javax.print包以及它的子包javax.print和javax.print.event和javax.print.attribute中。​

要实现打印操作,需要完成以下几个步骤:​

  • 定位一台打印机​
  • 指定打印内容的格式​
  • 设置打印属性​
  • 设置内容​
  • 打印​

其中第三步一般通过一个对话框完成,从JDK1.4开始ServiceUI打印对话框,其界面如图22-4所示。​

第二十二章《记事本》第2节:记事本功能实现_记事本

图22-4打印属性对话框​

打印操作由doPrint()方法完成,其实现过程如下:​

//调用打印对话框,给用户打印文档
void doPrint()
try
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor, pras);
PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
PrintService service = null;
service=ServiceUI.printDialog(null, 100, 100, printService, defaultService, flavor, pras);
if (service != null)
DocPrintJob job = service.createPrintJob();
DocAttributeSet das = new HashDocAttributeSet();
Doc doc = new SimpleDoc(text.getText().getBytes(), flavor, das);
job.print(doc, pras); //进行文件的打印

catch (Exception e)
JOptionPane.showMessageDialog(this, "打印任务无法完成");

22.2.6查找功能

查找功能对话框由FindDialog类实现,它是对话框类JDialog的子类。由于查找时是在查找对话框中设置关键字并且在NoteBookFrame类表示文本区的text组件中完成。从界面上来看,text是一个文本区,而从代码的角度来看text是NoteBookFrame的属性。为了访问这个属性,可以通过构造方法的参数把这个属性传递给FindDialog类对象,这样当找到关键字时就能操作这个text组件,因此FindDialog类的构造方法应设计为:​

public FindDialog(JFrame owner, JTextArea text) 
super(owner,false);
init(text);

如果能找到关键字,则调用text的select()方法选中关键字,如果找不到关键字,则弹出一个对话框提示用户。限于篇幅,查找对话框的实现过程暂不给出,而在22.3小节的项目完整代码中一并给出。​

22.2.7设置字体功能

设置字体对话框由FontDialog类表示,FontDialog也是JDialog的子类。设置字体对话框的界面如图22-2所示,从图中可以看出:对话框中有三个列表框,用户可以在这三个列表框中分别选择字体、字形和大小,当单击“确定”按钮后就能修改记事本中的字体。​

在程序中,打开设置字体对话框的方法是doChangeFont(),其实现过程如下:​

//设置字体​
void doChangeFont()
if (myFontDialog == null)
myFontDialog = new FontDialog(this);

if (myFontDialog.showFontDialog() == FontDialog.OK)
text.setFont(myFontDialog.getFont());//获得对话框返回的字体并以它作为记事本字体​

22.2.8退出记事本

当用户单击“退出”菜单项时,程序应该完成以下操作。​

  • 如果文件已经被保存,则直接退出。​
  • 如果文件没有被保存,则弹出对话框询问用户是否要保存文件。​
  • 如果用户选择不保存,则直接退出。​
  • 如果用户选择取消,则关闭对话框。​

为了完成以上操作,需要定义两个关键的boolean型变量:​

  • changed:用来标识文件是否已经被修改。​
  • haveName:用来标识文件是否有名字,实际上也是标识文件是不是新文件。​

退出操作由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;


本文字版教程还配有更详细的视频讲解,小伙伴们可以点击这里观看。

以上是关于《记事本》第2节:记事本功能实现的主要内容,如果未能解决你的问题,请参考以下文章

《记事本》第1节:记事本项目简介

上机题目(初级)- 用数组实现记事本+光标和删除(Java)

《斗地主游戏》第2节:系统功能实现

作业三:用c#实现一个记事本

C#简易记事本的实现

Win 7 如何批量提取指定文件夹下的所有文件名称及其路径?