1、文本编辑器的设计与实现
设计一个类似于Windows记事本(Notepad)的Java程序。可以打开、新建、保存一个文本文件;对选中的文本进行各种编辑操作(设置字体、字号、字型、对齐方式、背景、前景色、复制、粘贴、剪切、查找、替换等);在文本中能够插入对象。
******************-------main函数-----------------------*****************************
public class ex
{
public static void
main(String[] args)
{
new Notepad();
}
}
****************---------主要实现框架函数Notepad-----------***************************
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
//import java.awt.datatransfer.Clipboard;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.undo.UndoManager;
//import javax.swing.text.PlainDocument;public class Notepad extends JFrame
implements ActionListener ,MouseListener
{private static final long
serialVersionUID = 1L;
private File file;
private JTextArea text;
private JMenu menu[];
private JFileChooser fchooser;
private PrinterJob prtMe;
private JCheckBoxMenuItem checkboxmenuitem;
private JPopupMenu popupmenu;
private UndoManager myundo = new
UndoManager();
//UndoManager 管理 UndoableEdit
列表,提供撤消或恢复适当编辑的方法。
//FindJFrame findnext;
//Clipboard
clipbd=getToolkit().getSystemClipboard();public Notepad()
{
super("Notepad");
Dimension dim =
getToolkit().getScreenSize(); //获得屏幕分辨率
this.setBounds(dim.width/4,dim.height/4,dim.width/2,dim.height/2);//窗口大小一半、居中
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
text = new JTextArea("Welcom");
text.setLineWrap(true); //JTextArea默认下可以换行
text.getDocument().addUndoableEditListener(myundo);
this.getContentPane().add(new JScrollPane(text)); //JTextField加滚动条
JMenuBar menubar = new
JMenuBar(); //加菜单栏
this.setJMenuBar(menubar);
String[] menustr = {"文件","编辑","格式","查看","帮助"};
menu = new JMenu[menustr.length];
for(int i=0;i
{
menu[i] = new JMenu(menustr[i]);
menubar.add(menu[i]);
}
Filemenu();
Editmenu();
Formatmenu();
watchmenu();
helpmenu();
//加弹出菜单
text.addMouseListener(this); //JTextField中加鼠标监听器
mypopupmenu();
text.add(popupmenu); //把弹出菜单加在JTextField中
//加工具栏
JToolBar toolbar=new JToolBar();
this.getContentPane().add(toolbar,"North");
JButton bcreatfile =new JButton("新建");
bcreatfile.addActionListener(this);
toolbar.add(bcreatfile);
JButton bopen=new JButton("打开",new ImageIcon("open.gif"));
bopen.addActionListener(this);
toolbar.add(bopen);
JButton bsave=new JButton("保存",new ImageIcon("save.gif"));
bsave.addActionListener(this);
toolbar.add(bsave);
JButton bundo=new JButton("撤消");
bundo.addActionListener(this);
toolbar.add(bundo);
JButton bredo=new JButton("恢复");
bredo.addActionListener(this);
toolbar.add(bredo);
this.setVisible(true);
this.file=null;
this.fchooser=new JFileChooser(new
File(".","")); //文件对话框的初始路径是当前路径
this.fchooser.setFileFilter(new
FileNameExtensionFilter("文本文件(*.txt)","txt")); //设置文件过滤器
prtMe = PrinterJob.getPrinterJob();
//PrinterJob
类是控制打印的主要类。应用程序调用此类中的方法设置作业、(可选地)调用与用户的打印对话框,然后打印作业的页面。
}public Notepad(File
file) {
this();
if(file!=null)
{
this.file=file;
this.text.setText(this.file.getName());
this.setTitle(this.file.getName());
}
} public Notepad(String filename)
{
this(new File(filename));
} private
void mypopupmenu()
{
popupmenu=new
JPopupMenu();
String
menuitemstr[]={"撤消","恢复","剪切","复制","粘贴","全选","字体"};
JMenuItem popupmenuitem[]=new
JMenuItem[menuitemstr.length];
for(int
i=0;i
{
popupmenuitem[i]=new
JMenuItem(menuitemstr[i]);
if(i==1||i==4||i==5)
popupmenu.addSeparator();
popupmenu.add(popupmenuitem[i]);
popupmenuitem[i].addActionListener(this); }
//为弹出菜单中的恢复、剪切、复制、粘贴、全选 增加快捷方式
popupmenuitem[2].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,InputEvent.CTRL_MASK));
popupmenuitem[3].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,InputEvent.CTRL_MASK));
popupmenuitem[4].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,InputEvent.CTRL_MASK));
popupmenuitem[5].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,InputEvent.CTRL_MASK));
}private void Filemenu()
{
String menuitemstr[] = {"新建"
,"打开","保存","另存为","页面设置","打印","退出"};
JMenuItem menuitem[]=new
JMenuItem[menuitemstr.length];
for(int
i=0;i
{
menuitem[i]=
new JMenuItem(menuitemstr[i]);
menuitem[i].addActionListener(this);
menu[0].add(menuitem[i]);
if(i==3||i==5)
menu[0].addSeparator(); //加菜单分隔符
} } private void
Editmenu()
{
String
menuitemstr[]={"撤消","恢复","剪切","复制","粘贴","删除","查找","查找下一个","替换","转到","全选","时间/日期"};
JMenuItem menuitem[]=new
JMenuItem[menuitemstr.length];
for(int
i=0;i
{
menuitem[i]=new
JMenuItem(menuitemstr[i]);
menuitem[i].addActionListener(this);
menu[1].add(menuitem[i]);
if(i==1||i==5||i==9)
menu[1].addSeparator();
}
menuitem[9].setEnabled(false);///"转到"为阴影,没有作用
menuitem[9].removeActionListener(this);
}
private void Formatmenu()
{
checkboxmenuitem = new
JCheckBoxMenuItem("自动换行",true); //true表示默认状态可以换行
checkboxmenuitem.addActionListener(this);
menu[2].add(checkboxmenuitem);
JMenuItem menuitem = new JMenuItem("字体");
menuitem.addActionListener(this);
menu[2].add(menuitem);
}
private void
watchmenu()
{
JMenuItem menuitem = new
JMenuItem("查看状态栏");
//未加单击按扭监听器
menu[3].add(menuitem);
} private void helpmenu()
{
JMenuItem menuitem1 = new
JMenuItem("帮助主题");
//帮助主题没有加单击事件监听器
menu[4].add(menuitem1);
menu[4].addSeparator();
JMenuItem menuitem2 = new
JMenuItem("关于记事本");
// menuitem2.addActionListener(this);
menu[4].add(menuitem2); }
// public void writeToFile(String
lines) //将字符串lines写入到当件文本文件中
{
try
{
FileWriter
fout=new FileWriter(this.file);
fout.write(lines+"\n");
fout.close();
}
catch(IOException ioex)
{
JOptionPane.showMessageDialog(this,"有IO错,写入"+file.getName()+"文件不成功");
}
}
//
public
String
readFromFile() //将当前文本文件中的内容读出,以lines返回
{
char lines[]=null;
try
{
FileReader
fin=new FileReader(this.file);
lines=new
char[(int)this.file.length()];
fin.read(lines);
fin.close();
}
catch(FileNotFoundException
fe)
{
JOptionPane.showMessageDialog(this,"""+this.file.getName()+""文件不存在");
}
catch(IOException ioex)
{
JOptionPane.showMessageDialog(this,"IO错,读入"+file.getName()+"文件不成功"); }
finally
{
return new
String(lines);
}
}
//
public void actionPerformed(ActionEvent
e) {
if(e.getActionCommand()=="新建") {
this.file=null;
this.setTitle("未命名");
this.text.setText("");
}
else
if(e.getActionCommand()=="打开"&&fchooser.showOpenDialog(this)==JFileChooser.APPROVE_OPTION) //点击打开,显示打开对话框,选中文件后选择确定(确定以JFileChooser.APPROVE_OPTION(int类型)返回
{
this.file=fchooser.getSelectedFile();
this.setTitle(this.file.getName());
this.text.setText(this.readFromFile());
}
else
if(e.getActionCommand()=="保存"&&this.file!=null) //保存非空文件,不显示保存文件对话框 this.writeToFile(this.text.getText());
else
if((e.getActionCommand()=="保存"&&file==null||e.getActionCommand()=="另存为")&&fchooser.showSaveDialog(this)==JFileChooser.APPROVE_OPTION) //显示保存(空文件)或点击另存为按扭,出现保存对话框,点击确定(点击确定后会返回 JFileChooser.APPROVE_OPTION
{
this.file=fchooser.getSelectedFile(); //file为当前选中的文件
if(!file.getName().endsWith(".txt"));
this.file=new
File(file.getAbsolutePath()+".txt");
this.writeToFile(this.text.getText());
this.setTitle(this.file.getName());
}
else
if(e.getActionCommand()=="页面设置") prtMe.printDialog(); //显示找印对话框,供用户更改打印属性
else
if(e.getActionCommand()=="打印") {
try{
prtMe.print();//打印一组页面
}
catch(Exception ew)
{
JOptionPane.showMessageDialog(this,
"找不到打印机");
}
}
else
if(e.getActionCommand()=="退出") {
if(JOptionPane.showConfirmDialog(this,"终止当前程序运行?")==0)
System.exit(0);
}
else
if(e.getActionCommand()=="撤消"||e.getActionCommand()=="恢复") {
if(e.getActionCommand()=="撤消")
{
if(myundo.canUndo())
myundo.undo(); else
JOptionPane.showMessageDialog(this,"无法撤消");
}
else
{
if(myundo.canRedo())
myundo.redo(); else
JOptionPane.showMessageDialog(this,"无法恢得");
}
}
else
if(e.getActionCommand()=="剪切") {
text.cut();
// JOptionPane.showMessageDialog(this,"剪切");
}
else
if(e.getActionCommand()=="粘贴") {
text.paste();
// JOptionPane.showMessageDialog(this,"粘贴");
}
else
if(e.getActionCommand()=="删除") //replaceRange(String,start,end)用指定替换文本 text.replaceRange("",
text.getSelectionStart(),text.getSelectionEnd());//以空字符串代串选中的范围
else
if(e.getActionCommand()=="查找") { new
FindJFrame(text);
}
else
if(e.getActionCommand()=="查找下一个") {
FindJFrame
findnext=new FindJFrame(text);
findnext.setTitle("查找下一个");
findnext.setStart(text.getSelectionStart());
findnext.setEnd(text.getSelectionEnd()); }
else
if(e.getActionCommand()=="替换") {
new
ReplaceJFrame(text);
}
else
if(e.getActionCommand()=="全选") text.selectAll();
else
if(e.getActionCommand()=="时间/日期") //在JTextArea后追加显示系统当前时间 {
Calendar time
=Calendar.getInstance(); text.append(time.HOUR_OF_DAY+":"+time.MINUTE+" "+time.YEAR+"-"+time.MONTH+"-"+time.DAY_OF_MONTH+"\r");
}
else
if(e.getActionCommand()=="自动换行") {
text.setLineWrap(checkboxmenuitem.getState()); }
else
if(e.getActionCommand()=="字体") {
new
WordStyle(text);
}
}
public void mouseClicked(MouseEvent mec)
{
if(mec.getModifiers()==MouseEvent.BUTTON3_MASK)
popupmenu.show(text,mec.getX(),mec.getY()); //在鼠标点击的地方显示弹出菜单
}
public void mousePressed(MouseEvent mep) {}
public void mouseReleased(MouseEvent mre)
{}
public void mouseEntered(MouseEvent med) {}
public void mouseExited(MouseEvent me) {}
public void mouseDragged(MouseEvent mdg) {}
}
//PrintWriter p = new PrintWriter(this);
// PrintDocument a=new PrintDocument();
// new PlainDocument.Print();
//PrintJob
P=Toolkit.getDefaultToolkit().getPrintJob(this,"ok",null);
*********************-----------查找对话框------------***************************
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FindJFrame extends JFrame
implements ActionListener{ private
JTextArea text;
private JTextField findstr;
private JButton btn_findnext,btn_cannel;
private int start=0,end=0;
private final int
FIND=1; //找到标志
private int
flag=0; //标志是否找到
public FindJFrame()
{ super("查找");
this.setBounds(200,300,200,200);
this.setLayout(new
GridLayout(2,1));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
Panel panel1=new Panel();
panel1.setLayout(new
FlowLayout());
this.getContentPane().add(panel1);
panel1.add(new
Label("查找内容"));
findstr=new
JTextField(15);
panel1.add(findstr);
btn_findnext=new
JButton("查找下一个");
btn_findnext.addActionListener(this);
panel1.add(btn_findnext);
Panel panel2=new Panel();
this.getContentPane().add(panel2);
// panel2.add(new
JLabel("方向"));
//JButton
this.setResizable(false);
this.setVisible(true);
}
public FindJFrame(JTextArea
text)
{ this();
this.text=text;
end=text.getText().length();
}
public void
setfindstr(String str) //设置要查找的字符串
{ this.findstr.setText(str);
}
public int
getStart() //获得选中文本的起始位置
{ return
start;
}
public int
getEnd() //选中文本的终止位置
{ return
end;
}
public void setTitle(String
name) //设置文本标题
{ super.setTitle(name);
}
public void setStart(int
start) //设置鼠标起始位置
{ if(start>=0)
this.start=start;
else start=0;
}
public void setEnd(int
end) //设置鼠标终止位置
{ if(end>=0)
this.end=end;
else
end=text.getText().length();
}
public boolean
isFind() //判断是否找到
{ if(flag==FIND)
return
true;
else return false;
}
public void find()
{ flag=0;
if(start<0)
{
JOptionPane.showMessageDialog(this,"位置超出范围");
return
;
}
String
str=text.getText().substring(start,end); int
findstart=str.indexOf(findstr.getText()); //没有找到findstr的话返加-1
if(findstart!=-1)//找到
flag=FIND;
else
{
text.setSelectionStart(end);
text.setSelectionEnd(end);
return
;
}
System.out.println("findstart=
"+findstart);
text.setSelectionStart(start+findstart);
int
findend=start+findstart+findstr.getText().length();
text.setSelectionEnd(findend); start=findend;
}
public void
actionPerformed(ActionEvent e) //点击"查找下一个"
{
if(e.getSource()==btn_findnext)
{
find();
if(!isFind())
JOptionPane.showMessageDialog(this,"没有找到");
}
}
}
************************-------------替换对话框-------------*********************
//在FindJFrame的基础下实现替换功能
import java.awt.*;
import java.awt.event.*; //Action
import javax.swing.*;
import javax.swing.event.*; //Caret
public class ReplaceJFrame extends JFrame
implements
ActionListener,CaretListener{ private static final long serialVersionUID =
1L;
private JTextArea text;
private JTextField text_find,text_replace;
private JButton btn_findnext ,
btn_replace,btn_replaceall;
FindJFrame findjframe ;
public
ReplaceJFrame()
{ super("替换");
this.setBounds(200,200,400,200);
// this.setLayout(new
GridLayout(5,1));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(new
FlowLayout());
Container
container=this.getContentPane();
JPanel panel1=new
JPanel(); //Panel默认情况下是FlowLayout
container.add(panel1);
panel1.add(new JLabel("查找内容(N):
"));
text_find=new
JTextField("",20);
panel1.add(text_find);
JPanel panel2=new
JPanel();
container.add(panel2);
btn_findnext=new
JButton("查找下一个");
btn_findnext.addActionListener(this);
panel2.add(btn_findnext);
JPanel panel3=new
JPanel();
container.add(panel3); panel3.add(new
JLabel("替换为(P): "));
text_replace=new
JTextField("",20);
panel3.add(text_replace);
JPanel panel4=new
JPanel();
container.add(panel4);
btn_replace=new
JButton("替换");
btn_replace.addActionListener(this);
panel4.add(btn_replace);
JPanel panel5=new
JPanel();
container.add(panel5);
btn_replaceall=new
JButton("全部替换(A)");
btn_replaceall.addActionListener(this);
panel5.add(btn_replaceall);
this.setResizable(false);
this.setVisible(true);
}
public
ReplaceJFrame(JTextArea text)
{ this();
this.text=text; findjframe = new
FindJFrame(this.text);
findjframe.setVisible(false);
findjframe.setStart(0);
findjframe.setEnd(text.getText().length()); }
public void
caretUpdate(CaretEvent e)
{
findjframe.setfindstr(text_find.getText());
}public void actionPerformed(ActionEvent
e) {
{
findjframe.setfindstr(text_find.getText());
if(e.getSource()==btn_findnext)
{
findjframe.find();
if(!findjframe.isFind())
JOptionPane.showMessageDialog(this,"没有找到"+text_find.getText());
}
else
if(e.getSource()==btn_replace) {
if(text_replace.getText()=="")
{
JOptionPane.showMessageDialog(this,"请输入要替换的内容");
return
;
}
if(findjframe.isFind()) //调用find后,会把找到的字符串选中
{
String
tempstr=text.getText().substring(text.getSelectionStart(),
text.getSelectionEnd());
if(tempstr.equals(text_find.getText())) //找到了 用text_replace替换
text.replaceRange(text_replace.getText(),
text.getSelectionStart(),
text.getSelectionEnd()); }
}
else
if(e.getSource()==btn_replaceall) //从文本开头,替换所有
{
if(text_replace.getText()=="")
{
JOptionPane.showMessageDialog(this,"请输入要替换的内容");
return
;
}
int
len=text.getText().length();
findjframe.setStart(text.getSelectionStart());
findjframe.setEnd(len);
findjframe.find();
while(findjframe.isFind())
{ String
tempstr=text.getText().substring(text.getSelectionStart(),
text.getSelectionEnd());
if(tempstr.equals(text_find.getText()))
{
text.replaceRange(text_replace.getText(),
text.getSelectionStart(), text.getSelectionEnd());
}
findjframe.find();
}
}
}
}
}
**********************----------字体设置对话框-------------**********************
//功能:修改字体、字形、字号,JTextArea的前景色、背景色、对齐方式(没实现),以及用JTextArea
present预浏当前设置效果
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class
WordStyle extends JFrame implements
ActionListener{ private JComboBox
wordname,wordstyle,wordsize; //组合框
private JRadioButton
fontleft,fontcenter,fontright; //单选按钮
private JTextField
showfrecolor,showbackcolor; //显示当前选择的前景色背景色预浏
private JButton
frecolorchoose,backcolorchoose; private JTextArea text,present;
public WordStyle()
{ super("字体");
this.setBounds(200,200,500,500);
this.setLayout(new
GridLayout(4,1));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel1=new
JPanel();
this.getContentPane().add(panel1);
//panel1.setLayout(new
GridLayout(2,3));
panel1.setSize(500,200);
panel1.add(new
JLabel("字体")); GraphicsEnvironment
ge=GraphicsEnvironment.getLocalGraphicsEnvironment(); String[]
fontName=ge.getAvailableFontFamilyNames(); //获取系统字体
wordname=new
JComboBox(fontName);
wordname.addActionListener((ActionListener)
this);
panel1.add(wordname);
panel1.add(new
JLabel(" 字形"));
String[]
fontstyle={"常规","加粗","倾斜","加粗 倾斜"};
wordstyle=new
JComboBox(fontstyle);
wordstyle.addActionListener(this);
panel1.add(wordstyle);
panel1.add(new
JLabel(" 字号")); //本想加数字,但不知道怎么弄
String[] fontsize={
"5","5.5","6.5","7.5","8","9","10","11","12","13","14","15","16","17","18","19","20",
"24","28","30","40","50","60","70","80","90","100"};
wordsize=new
JComboBox(fontsize);
wordsize.setSelectedItem("16");
wordsize.addActionListener(this);
panel1.add(wordsize);
JPanel panel2=new
JPanel();
this.getContentPane().add(panel2);
panel2.setLayout(new
GridLayout(1,2));
panel2.setSize(500,100);
JPanel panel21=new
JPanel(); //前景颜色选择面板
panel2.add(panel21);
panel21.setLayout(new
FlowLayout());
// panel21.add(new
JLabel("字体颜色(C): "));
frecolorchoose = new
JButton("前景色");
frecolorchoose.addActionListener(this);
panel21.add(frecolorchoose);
showfrecolor=new
JTextField(10);
showfrecolor.setBackground(Color.black);
panel21.add(showfrecolor);
JPanel panel22=new
JPanel(); /背景字体对齐面板
panel2.add(panel22);
panel22.setLayout(new
FlowLayout());
// panel22.add(new
JLabel("字体颜色(C): "));
backcolorchoose = new
JButton("背景色");
//backcolorchoose.setSize(80,80);
backcolorchoose.addActionListener(this);
panel22.add(backcolorchoose);
showbackcolor=new
JTextField(10);
panel22.add(showbackcolor);
JPanel panel3 =new
JPanel();
this.getContentPane().add(panel3);
panel3.setSize(400,100);
ButtonGroup group=new
ButtonGroup();
fontleft =new JRadioButton("左对齐",true);
group.add(fontleft);
panel3.add(fontleft);
fontleft.addActionListener(this); fontcenter =new
JRadioButton("居中");
group.add(fontcenter);
panel3.add(fontcenter);
fontcenter.addActionListener(this); fontright =new
JRadioButton("右对齐");
group.add(fontright);
panel3.add(fontright);
fontright.addActionListener(this);
JPanel panel4 =new
JPanel();
this.getContentPane().add(panel4);
panel4.setSize(400,200);
char[] space=new
char[30];
java.util.Arrays.fill(space,'
');
present=new JTextArea("\n"+new
String(space)+"yaing's present");
present.setLineWrap(true);
panel4.add(present);
present.setRows(3);
present.setColumns(30);
present.setEditable(false);
this.setResizable(false);
this.setVisible(true);
}
public WordStyle(JTextArea
text)
{ this();
this.text=text;
}public void actionPerformed(ActionEvent
e)
{
int size=0;
if(e.getSource() instanceof
JComboBox) {
try
{
String
name=(String)(String)wordname.getSelectedItem();
int
style=this.text.getFont().getStyle();
//粗体第1个位置为1,斜体第二个位置为1
style=style^wordstyle.getSelectedIndex();
size=Integer.parseInt((String)(wordsize.getSelectedItem()));
if(size<5||size>100)
throw
new Exception("fontsizeException");
this.present.setFont(new
Font(name,style,size));
this.text.setFont(new
Font(name,style,size));
}
catch(NumberFormatException
nfe)
{
JOptionPane.showMessageDialog(this,(String)wordsize.getSelectedItem()+"不能转化成整数");
}
catch(Exception
ec)
{
if(ec.getMessage()=="fontsizeException")
JOptionPane.showMessageDialog(this,size+"
字号不合适(5,100)");
}
}
if(e.getSource() instanceof JRadioButton)
{ // this.add(new
JScrollPane(textPane));
}
if(e.getSource() instanceof JButton)
{ Color
color;
if(e.getSource()==frecolorchoose)
{
color=JColorChooser.showDialog(this,"前景色选择",Color.black); showfrecolor.setBackground(color);
this.present.setForeground(color);
this.text.setForeground(color);
}
else
{
color=JColorChooser.showDialog(this,"背景色选择",Color.white);
showbackcolor.setBackground(color);this.present.setBackground(color);
this.text.setBackground(color);
} }
}
}
还未解决的几个问题
1、对齐方式没有实现
JTextArea里面没有封装好的实现对齐方式的方法,在网上查了一下,JTextPane配合SimpleAttributeSet可以实现,但我想用JTextArea
,于是自已写了一个函数,但没有实现,因为我无法正确取出一行里到底有多少个字符,这个问题纠结了好久,还是没有弄出来。
2、各对象生命周期的问题
不大明白FindJFrame的生命周期与Notepad的到底是什么问题,我开始想,FindJFrame是在Notepad里创建的,所以关闭查找对话框不会影响到Notpad,但N次后运行的结果是:关掉查找对话框后,主框架也就消失了。