文章目录

  • 前言
  • 一、主类My_Frame
  • 二、外部字体设置类MQFontChooser
  • 三、特点
  • 参考文献


前言

使用java编写一个记事本,实现新建/保存/另存为/退出/撤销/恢复/复制/粘贴/剪切/删除/查找/转到/全选/自动换行/字体大小/字体颜色/背景颜色/状态栏/显示行号/帮助/关于等功能。时间显示创建了一个内部时钟类 Clock。显示行号创建了一个内部类TestLine。字体大小设置创建了一个外部类,使用package com;引用了外部类MQFontChooser。

一、主类My_Frame

package com;
import java.awt.EventQueue;  //事件调度线程
//布局
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Dimension;
//监听器
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//文件流
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
//菜单及工具
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.undo.UndoManager;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;

import java.awt.datatransfer.Clipboard;  //字符剪切板
import java.awt.datatransfer.StringSelection;  //连续字符器StringSelection
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
/*
 * 创建一个时钟类(一个内部类)
 */
import java.util.Calendar;
import java.util.GregorianCalendar;
/*
 * 创建一个显示行号类(一个内部类)
 */
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;

public class My_Frame { 
	//创建窗口
	private JFrame my_frame;
	
	//创建文本域
	private JTextArea textArea;
	
	//创建布局
	private BorderLayout borderLayout;
	
	//创建控制面板
	private JPanel panel;
	
	//创建滚动面板
	private JScrollPane scrollpanel;  
	
	//创建工具栏_状态栏
	private JToolBar toolState;
	
	//创建菜单栏
	private JMenuBar menuBar;
	
	//创建子菜单
	private JMenuItem itemNew;
	private JMenuItem itemOpen;
	private JMenuItem itemSave;
	private JMenuItem itemSaveAs;
	private JMenuItem itemPage;
	private JMenuItem itemPrint;
	private JMenuItem itemExit;
	private JMenuItem itemUndo;
	private JMenuItem itemRedo;
	private JMenuItem itemCut;
	private JMenuItem itemCopy;
	private JMenuItem itemPaste;
	private JMenuItem itemDelete;
	private JMenuItem itemFind;
	private JMenuItem itemTurnTo;
	private JMenuItem itemSelectAll;
	private JCheckBoxMenuItem itemNextLine;
	private JMenuItem itemFont;
	private JMenuItem itemColor;
	private JMenuItem itemFontColor;
	private JCheckBoxMenuItem itemStatement;
	private JCheckBoxMenuItem itemLineNumber;
	private JMenuItem itemSearchForHelp;
	private JMenuItem itemAboutNote;
	
	//创建鼠标右键弹窗
	private JPopupMenu popupMenu;
	//鼠标右键子菜单
	private JMenuItem popM_Undo;
	private JMenuItem popM_Redo;
	private JMenuItem popM_Copy;
	private JMenuItem popM_Paste;
	private JMenuItem popM_Cut;
	private JMenuItem popM_Delete;
	private JMenuItem popM_SelectAll;
			
	int flag = 0;  //用于判断文档保存状态
	String currentPath = null ;  //当前文件路径
	String currentFileName = null;  //当前文件名
    
    //文本的行数与列数与字数
	int linenum = 1;
	int columnnum = 1;
	int length = 0;
    
	public static JLabel tool_label_time; //工具栏时间标签,static定义为专属这个类
	
	//背景颜色
	JColorChooser jcc1 = null;
	Color color = Color.BLACK;
   
    //获取系统剪贴板
    public Clipboard clipboard = new Clipboard("系统剪切板");
    
    //撤销管理器
    public UndoManager undoMgr = new UndoManager();
    
    /*
     * 程序开始
     */
	public static void main(String[] args) {
		//创建事件调度线程(线程安全)
		EventQueue.invokeLater(
				new Runnable() {
					public void run() {
						//UI窗口界面
						try {
							//创建对象实例
							My_Frame liyangwei = new My_Frame();
							//对象实例中的窗口设置为可见的
							//liyangwei.my_frame.setVisible(true);
							//创建内部类实例
							//Clock clock = liyangwei.new Clock();
							//clock.start();  //时钟线程开始
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				});
	}

	//构造函数
	//UI窗口界面
	/***********************/
	public My_Frame() {
    	//创建窗口
		my_frame = new JFrame("liyangwei");//创建窗口
		my_frame.setSize(300,400);//设置窗口大小
		my_frame.setLocationRelativeTo(null);//设置窗口相对于指定组件的位置,null表示在中间
		my_frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置关闭窗口时关闭程序
    	
    	//创建文本域
    	textArea = new JTextArea();
    	
		//创建工具栏_状态栏
		toolState = new JToolBar();
		toolState.setSize(textArea.getSize().width, 10);
		
		GregorianCalendar c = new GregorianCalendar();  //获取系统时间	
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int min = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		tool_label_time = new JLabel("  Time:" + hour + ":" + min + ":" + second);  //此标签用来显示从时钟获取的时间
		
		JLabel tool_label1 = new JLabel("  第" + linenum + "行  ");
		JLabel tool_label2 = new JLabel("  第"+ columnnum + "列  ");
		JLabel tool_label3 = new JLabel("  共" + length + "字  ");
		
		toolState.add(tool_label1);
		toolState.addSeparator();  //添加分割线
		toolState.add(tool_label2);
		toolState.addSeparator();  //添加分割线
		toolState.add(tool_label3);
		toolState.addSeparator();  //添加分割线
		toolState.add(tool_label_time);
		textArea.addCaretListener(new CaretListener() {  //文本改变监听器
			public void caretUpdate(CaretEvent e) {
				JTextArea editArea = (JTextArea)e.getSource();
				try {
					int caretpos = editArea.getCaretPosition();
					linenum = editArea.getLineOfOffset(caretpos);
					columnnum = caretpos - textArea.getLineStartOffset(linenum);
					linenum += 1;
					tool_label1.setText("  第" + linenum + "行  ");
					tool_label2.setText("  第"+ columnnum + "列  ");
					length = My_Frame.this.textArea.getText().toString().length();
					tool_label3.setText("  一共" + length + " 字 ");
				} catch (Exception ex) {}
			}
		});
		//设置工具栏默认不可见
		toolState.setVisible(false);  
		//创建时钟实例(自己创建的一个内部时钟类)
		Clock clock = new Clock();
		//时钟线程开始
		clock.start();
		
		//创建菜单栏
		menuBar = new JMenuBar();
		
		//设置菜单栏为主菜单
		my_frame.setJMenuBar(menuBar);
		
		//创建菜单
		JMenu Menu_File = new JMenu("文件(F)");
		JMenu Menu_Edit = new JMenu("编辑(E)");
		JMenu Menu_Format = new JMenu("格式(O)");
		JMenu Menu_Check = new JMenu("查看(V)");
		JMenu Menu_Help = new JMenu("帮助(H)");
		
		//添加菜单到菜单栏
		menuBar.add(Menu_File);
		menuBar.add(Menu_Edit);
		menuBar.add(Menu_Format);
		menuBar.add(Menu_Check);
		menuBar.add(Menu_Help);
		
		//创建子菜单
		itemNew = new JMenuItem("新建(N)");
		itemOpen = new JMenuItem("打开(O)");
		itemSave = new JMenuItem("保存(S)");
		itemSaveAs = new JMenuItem("另存为(A)");
		itemPage = new JMenuItem("页面设置(U)");
		itemPrint = new JMenuItem("打印(P)");
		itemExit = new JMenuItem("退出(X)");
		
		itemUndo = new JMenuItem("撤销(U)");
		itemRedo = new JMenuItem("恢复(R)");
		itemCut = new JMenuItem("剪切(T)");
		itemCopy = new JMenuItem("复制(C)");
		itemPaste = new JMenuItem("粘贴(P)");
		itemDelete = new JMenuItem("删除(L)");
		itemFind = new JMenuItem("查找(F)");
		itemTurnTo = new JMenuItem("转到(G)");
		itemSelectAll = new JMenuItem("全选(A)");
		
		itemNextLine = new JCheckBoxMenuItem("自动换行(W)");
		itemFont = new JMenuItem("字体大小(F)");
		itemColor = new JMenuItem("背景颜色(C)");
		itemFontColor = new JMenuItem("字体颜色(I)");
		
		itemStatement = new JCheckBoxMenuItem("状态栏(S)");
		itemLineNumber = new JCheckBoxMenuItem("显示行号(N)");
		
		itemSearchForHelp = new JMenuItem("查看帮助(H)");
		itemAboutNote = new JMenuItem("关于记事本(A)");
	
		//复制粘贴剪切撤销恢复新建打开保存快捷键
		itemCopy.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.Event.CTRL_MASK));
		itemPaste.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.Event.CTRL_MASK));
		itemCut.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.Event.CTRL_MASK));
		itemUndo.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, java.awt.Event.CTRL_MASK));
		itemRedo.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.Event.CTRL_MASK));
		itemNew.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.Event.CTRL_MASK));
		itemOpen.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.Event.CTRL_MASK));
		itemSave.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.Event.CTRL_MASK));

		//添加撤销管理器
		textArea.getDocument().addUndoableEditListener(undoMgr);
	
		//子菜单添加监听器
		itemNew.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				actionNew();
			}
		});
		itemOpen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionOpen();
			}
		});
		itemSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionSave();
			}
		});
		itemSaveAs.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionSaveAs();
			}
		});
		itemPage.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionPage();
			}
		});
		itemPrint.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionPrint();
			}
		});
		itemExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionExit();
			}
		});
		itemUndo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionUndo();
			}
		});
		itemRedo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionRedo();
			}
		});
		itemCut.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionCut();
			}
		});
		itemCopy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionCopy();
			}
		});
		itemPaste.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionPaste();
			}
		});
		itemDelete.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionDelete();
			}
		});
		itemFind.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionFind();
			}
		});
		itemTurnTo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionTurnTo();
			}
		});
		itemSelectAll.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionSelectAll();
			}
		});
		itemNextLine.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionNextLine();
			}
		});
		itemFont.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionFont();
			}
		});
		itemColor.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionColor();
			}
		});
		itemFontColor.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionFontColor();
			}
		});
		itemStatement.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionStatement(itemStatement,toolState);
			}
		});
		itemLineNumber.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionLineNumber(itemLineNumber);
			}
		});
		itemSearchForHelp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionSearchForHelp();
			}
		});
		itemAboutNote.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionAboutNote();
			}
		});
		
		//创建鼠标右键弹窗
		popupMenu = new JPopupMenu();
		//添加鼠标右键弹窗监听器
		addPopup(textArea, popupMenu);
		//子菜单添加到右键弹窗菜单
		popM_Undo = new JMenuItem("撤销(Z)");
		popupMenu.add(popM_Undo);
		popM_Redo = new JMenuItem("恢复(R)");
		popupMenu.add(popM_Redo);
		popupMenu.add(new JSeparator());  //添加分割线
		popM_Copy = new JMenuItem("复制(C)");
		popupMenu.add(popM_Copy);
		popM_Paste = new JMenuItem("粘贴(V)");
		popupMenu.add(popM_Paste);
		popM_Cut = new JMenuItem("剪切(X)");
		popupMenu.add(popM_Cut);
		popM_Delete = new JMenuItem("删除(L)");
		popupMenu.add(popM_Delete);
		popupMenu.add(new JSeparator());  //添加分割线
		popM_SelectAll = new JMenuItem("全选(A)");
		popupMenu.add(popM_SelectAll);
		//鼠标右键子菜单添加动作监听器
		popM_Undo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionUndo();
			}
		});
		popM_Redo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionRedo();
			}
		});
		popM_Copy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionCopy();
			}
		});
		popM_Paste.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionPaste();
			}
		});
		popM_Cut.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionCut();
			}
		});
		popM_Delete.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionDelete();
			}
		});
		popM_SelectAll.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionSelectAll();
			}
		});
		
		//子菜单添加到菜单
		Menu_File.add(itemNew);
		Menu_File.add(itemOpen);
		Menu_File.add(itemSave);
		Menu_File.add(itemSaveAs);
		Menu_File.add(itemPage);
		Menu_File.add(itemPrint);
		Menu_File.add(itemExit);
		
		Menu_Edit.add(itemUndo);
		Menu_Edit.add(itemRedo);
		Menu_Edit.add(itemCut);
		Menu_Edit.add(itemCopy);
		Menu_Edit.add(itemPaste);
		Menu_Edit.add(itemDelete);
		Menu_Edit.add(itemDelete);
		Menu_Edit.add(itemFind);
		Menu_Edit.add(itemTurnTo);
		Menu_Edit.add(itemSelectAll);
		
		Menu_Format.add(itemNextLine);
		Menu_Format.add(itemFont);
		Menu_Format.add(itemColor);
		Menu_Format.add(itemFontColor);
		
		Menu_Check.add(itemStatement);
		Menu_Check.add(itemLineNumber);
		
		Menu_Help.add(itemSearchForHelp);
		Menu_Help.add(itemAboutNote);
				
		//创建滚动面板
		//textArea文本域设置滚动面板会有一个警告:Warning:the font "Times" is not available.
		scrollpanel = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		//scrollpane1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);//垂直滚动条显示
		//scrollpane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);//横轴滚动条不显示	
		
		//创建布局
		borderLayout = new BorderLayout();
		
		//创建控制面板
		panel = new JPanel(borderLayout);

		//控制面板添加组件
		panel.add(scrollpanel, BorderLayout.CENTER);
		panel.add(toolState, BorderLayout.SOUTH);
		
		//在窗口中添加控制面板
		my_frame.setContentPane(panel);
	
		//设置窗口为可见的
		my_frame.setVisible(true);
		
		//判断文档是否有变化
		isChanged();
		//窗口退出时,新建过或保存过文档的退出只有两种选择
		MainFrameWindowListener();
		
	}
	
	/*
	 * 
	 * 
	 * 
	 * 函数
	 * 
	 * 
	 */
	//判断文档是否有变化函数
	private void isChanged()
	{
		textArea.addKeyListener(new KeyAdapter() {
			public void keyTyped(KeyEvent e) {
				Character c = e.getKeyChar();
				if(c != null && !textArea.getText().toString().equals(""))
				{
					flag = 2; //文档改变过
				}
			}
		});
	}
	//新建的或保存过的退出只有两种选择
	private void MainFrameWindowListener()
	{//窗口关闭监听,当窗口关闭时,退出程序
		my_frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e)
			{
				atctionExit();  //程序退出函数
			}
		});
	}
	//添加鼠标右键弹窗监听器函数
	private static void addPopup(JTextArea component, final JPopupMenu popup)
	{
		component.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				if(e.isPopupTrigger()) //判断用户是否要求弹出菜单
				{
					showMenu(e);
				}
			}
			public void mouseRelease(MouseEvent e) {
				if(e.isPopupTrigger())
				{
					showMenu(e);
				}
			}
			public void showMenu(MouseEvent e) {
				popup.show(e.getComponent(), e.getX(), e.getY());
			}
		});
	}
	/*
	 * 
	 * 子菜单增加动作函数
	 */
	

	/*************************/
	//新建
	void actionNew() {
		if(flag == 0 || flag == 1) 
		{     //刚启动记事本为0,刚新建文档为1
			return;
		}
		else if(flag == 2 && this.currentPath == null)
		{
			int result = JOptionPane.showConfirmDialog(null, "是否将更改保存到无标题", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
			if(result == JOptionPane.OK_OPTION)
			{
				//没有路径,另存为
				this.atctionSaveAs();
			}
			else if(result ==  JOptionPane.NO_OPTION) 
			{
				this.textArea.setText("");
				my_frame.setTitle("无标题");
				flag = 1;
			}
			return;
		}
		else if(flag == 2 && this.currentPath != null)
		{
			int result = JOptionPane.showConfirmDialog(null, "是否将更改保存到无标题", this.currentPath + "?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
			if(result == JOptionPane.OK_OPTION)
			{
				//有路径直接保存
				this.atctionSave(); 
			}
			else if(result == JOptionPane.NO_OPTION)
			{
				this.textArea.setText("");
				my_frame.setTitle("无标题");
				flag = 1;
			}  
		}
		else if(flag == 3)
		{
			this.textArea.setText("");
			my_frame.setTitle("无标题");
		}
	}
	/*************************/
	//打开
	void atctionOpen() {
		if(flag == 2 && this.currentPath == null)
		{
			int result = JOptionPane.showConfirmDialog(null, "是否将更改保存到无标题?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
			if(result == JOptionPane.OK_CANCEL_OPTION) 
			{
				this.atctionSaveAs();
			}		
		}
		else if(flag == 2 && this.currentPath == null)
		{
			int result = JOptionPane.showConfirmDialog(null, "是否将更改保存到" + this.currentPath, "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
			if(result == JOptionPane.OK_OPTION)
			{
				this.atctionSave();
			}
		}
		//打开文件选择框
		JFileChooser choose = new JFileChooser();
		//选择文件
		int result = choose.showOpenDialog(null);
		if(result == JFileChooser.APPROVE_OPTION)
		{
			File file = choose.getSelectedFile();
			currentFileName = file.getName();
			currentPath = file.getAbsolutePath();
			flag = 3;
			my_frame.setTitle(this.currentPath);
			BufferedReader bufferedRead =  null;
			try {
				//建立文件流(字符流)
				InputStreamReader inputStream = new InputStreamReader(new FileInputStream(file), "GBK");
				bufferedRead = new BufferedReader(inputStream);  //动态绑定
				//读取内容
				StringBuffer  buf = new StringBuffer();
				String lineRead = null;
				while((lineRead = bufferedRead.readLine()) != null)
				{
					//System.getProperty("line.separator")相当于换行操作,可以在不同系统下运行换行操作
					buf.append(lineRead+System.getProperty("line.separator"));
				}
				//显示内容在文本框
				textArea.setText(buf.toString());
			} catch (FileNotFoundException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			} finally {
				try {
					if(bufferedRead != null) bufferedRead.close();
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		}
	}
	/*************************/
	//保存
	void atctionSave() {
		if(this.currentPath == null)
		{
			this.atctionSaveAs();
			if(this.currentPath == null)
			{
				return;
			}
		}
		FileWriter fw = null;
		//保存
		try {
			fw = new FileWriter(new File(currentPath));
			fw.write(textArea.getText());
			fw.flush();  //如果写入的数据比较少,则需要刷新缓存区
			flag = 3;
			my_frame.setTitle(this.currentPath);
		} catch (IOException e1) {
			e1.printStackTrace();
		}finally {
			try {
				if (fw != null) fw.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}	
	/*************************/
	//另存为
	void atctionSaveAs() {
		JFileChooser choose = new JFileChooser();
		//选择文件
		int result = choose.showSaveDialog(null);
		if (result == JFileChooser.APPROVE_OPTION) {
			//取得选择的文件
			File file = choose.getSelectedFile();
			FileWriter fw =null;
			//保存
			try {
				fw = new FileWriter(file);
				fw.write(textArea.getText());
				currentFileName=file.getName();
                currentPath = file.getAbsolutePath();
				fw.flush();  //如果写入的数据比较少,需要需要刷新缓存区
				this.flag = 3;
				my_frame.setTitle(currentPath);
			}catch (IOException e1) {
				e1.printStackTrace();
			}finally {
				try {
					if(fw != null) fw.close();
				} catch (IOException e1){
					e1.printStackTrace();
				} 
			}
		}
	}
	/*************************/
	void atctionPrint() {
		// TODO Auto-generated method stub

	}
	/*************************/
	//页面设置
	void atctionPage() {
		PageFormat pf = new PageFormat();
		PrinterJob.getPrinterJob().pageDialog(pf);
	}
	/*************************/
	//退出
	void atctionExit() {
		if(flag == 2 && currentPath == null)
		{
			//这是弹出小窗
			//刚启动记事本为0,刚新建文档为1
			int result = JOptionPane.showConfirmDialog(null, "是否将更改保存到无标题?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
			if(result == JOptionPane.OK_OPTION)
			{
				this.atctionSaveAs();
			}
			else if(result == JOptionPane.NO_OPTION)
			{
				//退出程序
				my_frame.dispose();
			}
		}
		else if(flag == 2 && currentPath != null)
		{
			int result = JOptionPane.showConfirmDialog(null, "是否将更改保存到" + currentPath +"?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
			if(result == JOptionPane.OK_OPTION)
			{
				this.atctionSave();
			}
			else if(result == JOptionPane.NO_OPTION)
			{
				//退出程序
				my_frame.dispose();
			}
		}
		else
		{
			int result = JOptionPane.showConfirmDialog(null, "确定关闭?", "系统提示", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
			if(result == JOptionPane.OK_OPTION)
			{
				//退出程序
				my_frame.dispose();
			}
		}
	}
	/*************************/
	//撤销
	void atctionUndo() {
		if(undoMgr.canUndo())
		{
			undoMgr.undo();
		}
	}
	/*************************/
	//恢复
	void atctionRedo() {
		if(undoMgr.canRedo())
		{
			undoMgr.redo();
		}
	}
	/*************************/
	//剪切
	void atctionCut() {
		atctionCopy();
		int start = this.textArea.getSelectionStart();  //标记开始位置
		int end = this.textArea.getSelectionEnd();  //标记结束位置
		//删除所选文段
		this.textArea.replaceRange("", start, end);
	}
	/*************************/
	//复制
	void atctionCopy() {
		//拖动选取文本
		String temp = this.textArea.getSelectedText();
		//把获取的内容复制到连续字符器,这个类继承了剪贴板接口
		StringSelection text = new StringSelection(temp);
		//把内容放在剪贴板
	    clipboard.setContents(text, null);
	}
	/*************************/
	//粘贴
	void atctionPaste() {
		//Transferable接口,把剪贴板的内容转换成数据
		Transferable contents = this.clipboard.getContents(this);
		//DataFalvor类判断是否能把剪贴板的内容转换成所需要数据类型
		DataFlavor flavor = DataFlavor.stringFlavor;
		//如果可以转换
		if(contents.isDataFlavorSupported(flavor));
		{
			String str;
			try {
				//开始转换
				str = (String)contents.getTransferData(flavor);
				//如果要粘贴时,鼠标已经选中了一些字符
				if(this.textArea.getSelectedText() != null)
				{
					int start = this.textArea.getSelectionStart();  //定位被选中的字符的开始位置
					int end = this.textArea.getSelectionEnd();  //定位被选中字符的开始位置
					this.textArea.replaceRange(str, start, end);  //把粘贴的内容替换成被选中的内容
				}
				else
				{
					//获取鼠标所在TextArea的位置
					int mouse = this.textArea.getCaretPosition();
					//在鼠标所在的位置粘贴内容
					this.textArea.insert(str, mouse);
				}
			} catch(UnsupportedFlavorException e) {
				e.printStackTrace();
			} catch(IOException e) {
				e.printStackTrace();
			} catch(IllegalArgumentException e) {
				e.printStackTrace();
			}
		}
	}
	/*************************/
	//删除
	void atctionDelete() {
		String tem = textArea.getText().toString();
		textArea.setText(tem.substring(0, textArea.getSelectionStart()));
	}
	/*************************/
	//查找与替换
	void atctionFind() {
		final JDialog findDialog = new JDialog(my_frame, "查找与替换", true); //“查找与替换对话框”
		Container con = findDialog.getContentPane();  //布局管理器
		con.setLayout(new FlowLayout(FlowLayout.LEFT));  //设置布局管理器
		JLabel searchContentLabel = new JLabel("查找内容(N):");
		JLabel replaceContentLabel = new JLabel("替换成为(N):");
		final JTextField findText = new JTextField(16);
		final JTextField replaceText = new JTextField(16);
		final JCheckBox matchcase = new JCheckBox("区分大小写");
		final JRadioButton up = new JRadioButton("向上(U)");
		final JRadioButton down = new JRadioButton("向下(D)");
		down.setSelected(true);  //down框默认选中
		JButton searchNext = new JButton("查找下一个(F)");
		JButton replace = new JButton("替换(R)");
		final JButton replaceAll = new JButton("全部替换(A)");
		searchNext.setPreferredSize(new Dimension(110, 22));
		replace.setPreferredSize(new Dimension(110, 22));
		replaceAll.setPreferredSize(new Dimension(110, 22));
		//“替换”按钮的事件处理
		replace.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(replaceText.getText().length() == 0 && textArea.getSelectedText() != null)
					textArea.replaceSelection("");
				if(replaceText.getText().length() > 0 && textArea.getSelectedText() != null)
					textArea.replaceSelection(replaceText.getText());	
			}
		});
		//"替换全部"按钮的事件处理
		replaceAll.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				textArea.setCaretPosition(0);  //将光标放到编辑区开头
				int a = 0;	//要替换的文本开头
				int b = 0;  //要替换的文本结尾
				int replaceCount = 0;  //替换多少处文本
				//提示要输入查找的文本
				if(findText.getText().length() == 0)
				{
					JOptionPane.showMessageDialog(findDialog, "请填写查找内容!", "提示", JOptionPane.WARNING_MESSAGE);
					findText.requestFocus(true);
					return;
				}
				while (a > -1)  //当indexOf()函数没有找到匹配到内容时,返回-1,即结束循环
				{
					int FindStartPos = textArea.getCaretPosition(); //获取编辑区中光标的位置
					String str1, str2;
					str1 = textArea.getText();  //获取编辑区的文本
					str2 = findText.getText();  //获取查找内容框中的文本
				
					if(textArea.getSelectedText() == null) //当执行textArea.select(a, a + b)之后就选中编辑框中的文本
					{
						//从编辑区的开头开始查找(前面已经将光标放到编辑区开头)
						a = str1.indexOf(str2, FindStartPos);  //第二个参数表示从第几个位置开始向后查,str2第一个出现的位
					}
					else
					{
						//查找下一个匹配的内容
						a = str1.indexOf(str2, FindStartPos - findText.getText().length()+1);
					}
					if(a > -1)
					{
						textArea.setCaretPosition(a);  //设置编辑区中光标开始的位置
						b = findText.getText().length(); 
						textArea.select(a, a + b);  //选中textArea文本框中的指定区域
					}
					else
					{
						if(replaceCount == 0)
						{
							JOptionPane.showMessageDialog(findDialog, "查不到您查找的内容!", "记事本", JOptionPane.INFORMATION_MESSAGE);
						}
						else
						{
							JOptionPane.showMessageDialog(findDialog, "成功替换" + replaceCount +"个匹配内容!", "替换成功", JOptionPane.INFORMATION_MESSAGE);
						}
					}
					if(replaceText.getText().length() == 0 && textArea.getSelectedText() != null)
					{
						textArea.replaceSelection("");  //先选中textArea文本框中的指定区域,然后调用此方法就可以将选中的区域文字替换为“”
						replaceCount++;
					}
					if(replaceText.getText().length() > 0 && textArea.getSelectedText() != null)
					{
						textArea.replaceSelection(replaceText.getText());  先选中textArea文本框中的指定区域,然后调用此方法就可以将选中的区域文字替换为replaceText.getText()
						replaceCount++;
					}
				}  //end while
			}
		}); //"替换全部"按钮的事件处理结束 
		// "查找下一个"按钮事件处理
		searchNext.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int a = 0, b = 0;
				int FindStartPos = textArea.getCaretPosition();
				String str1, str2, str3, str4, strA, strB;
				str1 = textArea.getText();
				str2 = str1.toLowerCase();  //把字符串全部转换成小写,而非字母字符则不变
				str3 = findText.getText();
				str4 = str3.toLowerCase();  //把字符串全部转换成小写,而非字母字符则不变
				//“区分大小写”的CheckBox被选中
				if(matchcase.isSelected())
				{
					strA = str1;
					strB = str3;
				}
				else 
				{
					strA = str2;
					strB = str4;
				}
				if(up.isSelected())  //判断up框是否被选中
				{
					if(textArea.getSelectedText() == null)
					{
						第二个参数表示从第几个位置开始向前查,strB第一个出现的位置
						a = strA.lastIndexOf(strB, FindStartPos - 1);
					}
					else
					{
						//第二个参数表示从第几个位置开始向前查,strB第一个出现的位置
						a = strA.lastIndexOf(strB, FindStartPos - findText.getText().length() - 1);
					}
				}
				else if(down.isSelected())  //判断down框是否被选中
				{
					if(textArea.getSelectedText() == null)  //判断textArea编辑区是否有被选中的文本
					{
						//第二个参数表示从第几个位置开始向后查,str2第一个出现的位置
						a = strA.indexOf(strB, FindStartPos);
					}
					else
					{
						//第二个参数表示从第几个位置开始向后查,str2第一个出现的位置
						a = strA.indexOf(strB, FindStartPos - findText.getText().length() + 1);
					}
				}
				if(a > -1)
				{
					textArea.setCaretPosition(a);  //设置编辑区中光标开始的位置
					b = findText.getText().length();
					textArea.select(a, a + b);  //选中textArea文本框中的指定区域
				}
				else
				{
					JOptionPane.showMessageDialog(null, "找不到您查找的内容!", "记事本", JOptionPane.INFORMATION_MESSAGE);
				}
			}
		}); //"查找下一个"按钮事件处理结束
		
		//"取消"按钮事件处理
		JButton cancel = new JButton("取消");
		cancel.setPreferredSize(new Dimension(110, 22));
		cancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				findDialog.dispose(); //退出窗口
			}
		});
		
		//创建"查找与替换"对话框的界面
		JPanel bottomPanel = new JPanel();  //下面板
		JPanel centerPanel = new JPanel();  //中面板
		JPanel topPanel = new JPanel();	    //上面板
		JPanel searchPanel = new JPanel();  //网格面板
		//设置网格面板
		searchPanel.setLayout(new GridLayout(2,1));
		searchPanel.add(searchNext);
		searchPanel.add(replace);
		//面板添加组件
		topPanel.add(searchContentLabel);
		topPanel.add(findText);
		topPanel.add(searchPanel);
		centerPanel.add(replaceContentLabel);
		centerPanel.add(replaceText);
		centerPanel.add(replaceAll);
		bottomPanel.add(matchcase);
		bottomPanel.add(up);
		bottomPanel.add(down);
		bottomPanel.add(cancel);
		//往面板容器中添加面板
		con.add(topPanel);
		con.add(centerPanel);
		con.add(bottomPanel);
		
		//设置"查找与替换"对话框的大小,不可变大小,位置和可见性
		findDialog.setSize(410, 210);  
		findDialog.setResizable(false);  //设置查找对话框不可以改变大小
		findDialog.setLocation(230, 280); //设置查找对话框的位置
		findDialog.setVisible(true);  //设置查找对话框为可见的
	}
	/*************************/
	//转到
	void atctionTurnTo() {
		final JDialog gotoDialog = new JDialog(my_frame, "转到下列行");
		JLabel gotoLabel = new JLabel("行数(L):");
		final JTextField linenum = new JTextField(5);
		linenum.setText("1");
		linenum.selectAll();
		JButton okButton = new JButton("确定");
		okButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int totalLine = textArea.getLineCount();
				int[] lineNumber = new int[totalLine +1];
				String s = textArea.getText();
				int pos = 0, t = 0;
				while(true) {
					pos = s.indexOf('\12', pos);
					if(pos == -1)
					{
						break;
					}
					lineNumber[t++] = pos++;
				}
				int gt = 1;
				try {
					gt = Integer.parseInt(linenum.getText());
				} catch (NumberFormatException efe) {
					JOptionPane.showMessageDialog(null, "请输入行数!", "提示", JOptionPane.WARNING_MESSAGE);
					linenum.requestFocus(true);
					return;
				}
				if(gt < 2 || gt >= totalLine)
				{
					if(gt < 2)
					{
						textArea.setCaretPosition(0);
					}
					else
					{
						textArea.setCaretPosition(s.length());
					}
				}
				else
				{
					textArea.setCaretPosition(lineNumber[gt - 2] + 1);
				}
				gotoDialog.dispose();
			}
		});
		JButton cancelButton = new JButton("取消");
		cancelButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				gotoDialog.dispose();
			}
		});
		Container con = gotoDialog.getContentPane();
		con.setLayout(new FlowLayout());
		con.add(gotoLabel);
		con.add(linenum);
		con.add(cancelButton);
		con.add(okButton);
		gotoDialog.setSize(200, 200);
		gotoDialog.setResizable(false);//设置窗口不可变
		gotoDialog.setLocation(300, 280);
		gotoDialog.setVisible(true);
	}
	/*************************/
	//全选
	void atctionSelectAll() {
		textArea.selectAll(); 
	}
	/*************************/
	//自动换行
	void atctionNextLine() {
		if(itemNextLine.isSelected())
		{   //自动换行打开
			textArea.setLineWrap(true);
		}
		else
		{   //自动换行关闭
			textArea.setLineWrap(false);
		}
	}
	/*************************/
	void atctionFont() {
		MQFontChooser fontChooser = new MQFontChooser(textArea.getFont());
		fontChooser.showFontDialog(my_frame);
		Font font = fontChooser.getSelectFont();
		//将字体设置到JTextArea中
		textArea.setFont(font);
	}
	/*************************/
	//背景颜色
	void atctionColor() {
		jcc1 = new JColorChooser();
		JOptionPane.showMessageDialog(null, jcc1, "选择背景颜色", -1);
		color = jcc1.getColor();
		textArea.setBackground(color);
	}
	/*************************/
	//字体颜色
	void atctionFontColor() {
		// TODO Auto-generated method stub
		jcc1 = new JColorChooser();
		JOptionPane.showMessageDialog(null, jcc1, "选择字体颜色", -1);
		color = jcc1.getColor();
		textArea.setForeground(color);
	}
	/*************************/
	//状态栏
	protected static void atctionStatement(JCheckBoxMenuItem itemStatement,JToolBar toolState) {
		// TODO Auto-generated method stub
		if(itemStatement.isSelected()) {
			toolState.setVisible(true);  //当选择状态栏时工具栏显示
		}
		else {
			toolState.setVisible(false);  //当不选择状态栏时工具栏不显示
		}	
	}
	/*************************/
	//显示行号
	void atctionLineNumber(JCheckBoxMenuItem itemLineNumber) {
		// TODO Auto-generated method stub
		if(itemLineNumber.isSelected()) {
			//当选择状态栏时工具栏显示
			TestLine view = new TestLine();
			view.setLineHeight(16);  //设置左边显示数字的行高
			scrollpanel.setRowHeaderView(view);
		}
		else {
			  //当不选择状态栏时工具栏不显示
			scrollpanel.setRowHeaderView(null);
		}	
	}
	/*************************/
	//查看帮助
	protected static void atctionSearchForHelp() {
		// TODO Auto-generated method stub
		JOptionPane.showMessageDialog(null, "liyangwei", "帮助", JOptionPane.PLAIN_MESSAGE);
	}
	/*************************/
	//关于记事本
	protected static void atctionAboutNote() {
		// TODO Auto-generated method stub
		JOptionPane.showMessageDialog(null, "this is my note v1.0", "关于", JOptionPane.PLAIN_MESSAGE);
	}

	/*
	 * 创建一个时钟类(一个内部类)
	 */
	class Clock extends Thread{
		public void run() {
			while(true) {
				/*
				SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-DD 'at' HH:mm:ss z");  //显示时间的格式import java.text.SimpleDateFormat;
				Date date = new Date(System.currentTimeMillis());  //获取时间import java.util.Date;
				System.println("Time:"+formatter.format(date) );
				*/
				GregorianCalendar time = new GregorianCalendar();
				int hour = time.get(Calendar.HOUR_OF_DAY);
				int min = time.get(Calendar.MINUTE);
				int second = time.get(Calendar.SECOND);
				My_Frame.tool_label_time.setText("  Time:" + hour + ":" + min + ":" + second);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException exception) {
					//发生错误时的信息提示
				}
			}
		}
	}
	/*
	 * 创建一个显示行号类(一个内部类)
	 */
	public class TestLine extends javax.swing.JComponent{
		private static final long serialVersionUID = 123456789;  //序列号
		private final Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 13);  //字体
		public final Color DEFAULT_BACKGROUD = new Color(228, 228, 228); //显示行号区域背景颜色
		public final Color DEFAULT_FOREGROUD = Color.red;  //数字行号的颜色
		public final int nHEIGHT = Integer.MAX_VALUE - 1000000;  //Integer.MAX_VALUE表示int数据类型的最大取值输是2147483647
		public final int MARGIN = 5;  
		private int lineHeight;      //数字行号的高度,例如lineHeight = 16;	
		private int fontLineHeight;
		private int start_temp = 0;
		private int currentRowWidth;  //显示行号区域的宽度
		private FontMetrics fontMetrics;
		public TestLine() {
			setFont(DEFAULT_FONT);  //设置字体
			setForeground(DEFAULT_FOREGROUD);  //设置字体颜色
			setBackground(DEFAULT_BACKGROUD);  //设置背景颜色
			setPreferredSize(9999);
		}
		public void setPreferredSize(int row) {
			int width = fontMetrics.stringWidth(String.valueOf(row));  //获取字体的宽度
			if(currentRowWidth < width)
			{
				currentRowWidth = width;
				setPreferredSize(new Dimension(2 * MARGIN + width + 1, nHEIGHT));  //设置显示行号区域最适合的大小,随窗口而变化	
			}
		}
		public void setFont(Font font) {
			super.setFont(font);  //继承父类的方法,设置字体
			fontMetrics = getFontMetrics(getFont());  //获取数字字体文本
			fontLineHeight = fontMetrics.getHeight();  //获取数字字体的高度
		}
		public int getLineHeight() {
			if(lineHeight == 0) {
				return fontLineHeight;
			}
			return lineHeight;
		}
		public void setLineHeight(int lineHeight) {
			if(lineHeight > 0) {
				this.lineHeight = lineHeight;
			}
		}
		public int getStartOffset() {
			return 4;  //获取补偿值
		}
		protected void paintComponent(Graphics g) {
			int nlineHeight = getLineHeight();   //获取行高
			int startOffset = getStartOffset();  //获取补偿值
			Rectangle drawHere = g.getClipBounds();
			g.setColor(getBackground());  //设置画笔颜色
			g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);  //画文本框
			g.setColor(getForeground());
			int startLineNum = (drawHere.y / nlineHeight) + 1;  //开始的行号
			int endLineNum = startLineNum + (drawHere.height / nlineHeight);  //最后的行号
			int start = (drawHere.y /nlineHeight) * nlineHeight + nlineHeight - startOffset;  
			for(int i = startLineNum; i <= endLineNum; ++i) {
				String lineNum = String.valueOf(i);  //新数字转换为字符串
				int width = fontMetrics.stringWidth(lineNum);  //获取新数字的宽度
				g.drawString(lineNum + " ", MARGIN + currentRowWidth - width -1, start);  //画出新数字
				start += nlineHeight;
			}
			setPreferredSize(endLineNum);
		}
	}
	
	
}

二、外部字体设置类MQFontChooser

package com;//引用com包中的类

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;

public class MQFontChooser extends JDialog {
	
	private static final long serialVersionUID = 12345678;  //序列号
	
	public static final int CANCEL_OPTION = 0;  //选择取消按钮的返回值
	public static final int APPROVE_OPTION = 1;  //选择确定按钮的返回值
	private static final String CHINA_STRING = "嘻嘻";   //中文预览字符串
	private static final String ENGLISH_STRING = "licanbin";  //英文预览的字符串
	private static final String NUMBER_STRING = "0123456789";  //数字预览的字符串
	private Font font = null; //预设字体,也是将来要返回的字体
	private Box box = null;  //字体选择器组件容器
	private JTextField fontText = null;  //字体文本框
	private JTextField styleText = null; //样式文本框
	private JTextField sizeText = null; //文字大小文本框
	private JTextField previewText = null; //预览文本框
	private JRadioButton chinaButton = null; //中文预览
	private JRadioButton englishButton = null; //英文预览
	private JRadioButton numberButton = null; //数字预览
	private JList fontList = null; //字体选择框
	private JList styleList = null; //样式选择器
	private JList sizeList = null; //文字大小选择器
	private JButton approveButton = null;  //确定按钮
	private JButton cancelButton = null;  //取消按钮
	private String [] fontArray = null; //所有字体
	private String [] styleArray = {"常规", "粗体", "斜体", "粗斜体"};  //所有样式
	private String [] sizeArray = {"8", "9", "10", "11", "12", "14", "16", "18", "20", "22","24", "26", "28", "36", "48", "初号", "小初", "一号", "小一", "二号","小二","三号", "小三", "四号", "小四", "五号","小五","六号", "小六", "七号", "八号"}; //所有预设字体大小
	private int [] sizeIntArray = {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 42, 36, 26, 24, 22, 18, 16, 15, 14, 12, 10, 9, 8, 7, 6, 5};
	private int returnValue = CANCEL_OPTION;  //返回的数值,默认取消
	
	//构造一个字体选择器
	public MQFontChooser() {
		new Font("宋体", Font.PLAIN, 12);
	}
	//使用给定的预设字体构造一个字体选择器
	public MQFontChooser(Font font) {
		setTitle("字体选择器");
		this.font = font;
		//初始化UI组件
		init();
		//添加监听器
		addListener();
		//按照预设字体显示
		setup();
		//基本设置
		setModal(true);
		setResizable(false);
		//自适应大小
		pack();
	}
	//初始化组件
	private void init() {
		//获取系统字体
		GraphicsEnvironment eq = GraphicsEnvironment.getLocalGraphicsEnvironment();
		fontArray = eq.getAvailableFontFamilyNames();
		//主容器
		box = Box.createVerticalBox();
		box.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
		fontText = new JTextField();
		fontText.setEditable(false);
		fontText.setBackground(Color.WHITE);
		styleText = new JTextField();
		styleText.setEditable(false);
		styleText.setBackground(Color.WHITE);
		sizeText = new JTextField("12");
		//给文字大小文本框使用的Document文档,制定了一些输入字符的规则
		Document doc = new PlainDocument() {
			public void insertString(int offs, String str, AttributeSet a) throws BadLocationException{
				if(str == null) {
					return;
				}
				if(getLength() >= 3) {
					return;
				}
				if(!str.matches("[0-9]+") && !str.equals("初号") && !str.equals("小初")&& !str.equals("一号") && !str.equals("小一") && !str.equals("二号") && !str.equals("小二")&& !str.equals("三号") && !str.equals("小三")&& !str.equals("四号") && !str.equals("小四")&& !str.equals("五号") && !str.equals("小五")&& !str.equals("六号") && !str.equals("小六")&& !str.equals("七号") && !str.equals("八号")) {
					return;
				}
				super.insertString(offs, str, a);
				sizeList.setSelectedValue(sizeText.getText(), true);
			}
		};
		sizeText.setDocument(doc);
		previewText = new JTextField(20);
		previewText.setHorizontalAlignment(JTextField.CENTER);
		previewText.setEditable(false);
		previewText.setBackground(Color.WHITE);
		chinaButton = new JRadioButton("中文预览", true);
		englishButton = new JRadioButton("英文预览");
		numberButton = new JRadioButton("数字预览");
		ButtonGroup bg = new ButtonGroup();
		bg.add(chinaButton);
		bg.add(englishButton);
		bg.add(numberButton);
		fontList = new JList(fontArray);
		styleList = new JList(styleArray);
		sizeList = new JList(sizeArray);
		approveButton = new JButton("确定");
		cancelButton = new JButton("取消");
		Box box1 = Box.createHorizontalBox();
		JLabel l1 = new JLabel("字体:");
		JLabel l2 = new JLabel("字形:");
		JLabel l3 = new JLabel("大小:");
		l1.setPreferredSize(new Dimension(165, 14));
		l1.setMaximumSize(new Dimension(165, 14));
		l1.setMinimumSize(new Dimension(165, 14));
		l2.setPreferredSize(new Dimension(95, 14));
		l2.setMaximumSize(new Dimension(95, 14));
		l2.setMinimumSize(new Dimension(95, 14));
		l3.setPreferredSize(new Dimension(80, 14));
		l3.setMaximumSize(new Dimension(80, 14));
		l3.setMinimumSize(new Dimension(80, 14));
		box1.add(l1);
		box1.add(l2);
		box1.add(l3);
		Box box2 = Box.createHorizontalBox();
		fontText.setPreferredSize(new Dimension(160, 20));
		fontText.setMaximumSize(new Dimension(160, 20));
		fontText.setMinimumSize(new Dimension(160, 20));
		box2.add(fontText);
		box2.add(Box.createHorizontalStrut(5));
		styleText.setPreferredSize(new Dimension(90, 20));
		styleText.setMaximumSize(new Dimension(90, 20));
		styleText.setMinimumSize(new Dimension(90, 20));
		box2.add(styleText);
		box2.add(Box.createHorizontalStrut(5));
		sizeText.setPreferredSize(new Dimension(80, 20));
		sizeText.setMaximumSize(new Dimension(80, 20));
		sizeText.setMinimumSize(new Dimension(80, 20));
		box2.add(sizeText);
		Box box3 = Box.createHorizontalBox();
		JScrollPane sp1 = new JScrollPane(fontList);
		sp1.setPreferredSize(new Dimension(160, 100));
		sp1.setMaximumSize(new Dimension(160, 100));
		sp1.setMinimumSize(new Dimension(160, 100));
		box3.add(sp1);
		box3.add(Box.createHorizontalStrut(5));
		JScrollPane sp2 = new JScrollPane(styleList);
		sp2.setPreferredSize(new Dimension(90, 100));
		sp2.setMaximumSize(new Dimension(90, 100));
		sp2.setMinimumSize(new Dimension(90, 100));
		box3.add(sp2);
		box3.add(Box.createHorizontalStrut(5));
		JScrollPane sp3 = new JScrollPane(sizeList);
		sp3.setPreferredSize(new Dimension(80, 100));
		sp3.setMaximumSize(new Dimension(80, 100));
		sp3.setMinimumSize(new Dimension(80, 100));
		box3.add(sp3);
		Box box4 = Box.createHorizontalBox();
		Box box5 = Box.createVerticalBox();
		JPanel box6 = new JPanel(new BorderLayout());
		box5.setBorder(BorderFactory.createTitledBorder("字符集"));
		box6.setBorder(BorderFactory.createTitledBorder("示例"));
		box5.add(chinaButton);
		box5.add(englishButton);
		box5.add(numberButton);
		box5.setPreferredSize(new Dimension(90, 95));
		box5.setMaximumSize(new Dimension(90, 95));
		box5.setMinimumSize(new Dimension(90, 95));
		box6.add(previewText);
		box6.setPreferredSize(new Dimension(90, 95));
		box6.setMaximumSize(new Dimension(90, 95));
		box6.setMinimumSize(new Dimension(90, 95));
		box4.add(box5);
		box4.add(Box.createHorizontalStrut(4));
		box4.add(box6);
		Box box7 = Box.createHorizontalBox();
		box7.add(Box.createHorizontalGlue());
		box7.add(approveButton);
		box7.add(Box.createHorizontalStrut(5));
		box7.add(cancelButton);
		box.add(box1);
		box.add(box2);
		box.add(box3);
		box.add(Box.createVerticalStrut(5));
		box.add(box4);
		box.add(Box.createVerticalStrut(5));
		box.add(box7);
		getContentPane().add(box);
	}
	//按照预设字体显示
	private void setup() {
		String fontName = font.getFamily();
		int fontStyle = font.getStyle();
		int fontSize = font.getSize();
		//如果预设的文字大小在选择列表中,则通过选择列表中的某项进行设值,否则直接将预设文字大小写入文本框
		boolean b = false;
		for(int i = 0; i < sizeArray.length; i++) {
			if(sizeArray[i].equals(String.valueOf(fontSize))) {
				b = true;
				break;
			}
		}
		if(b) {
			//选择文字大小列表中的某项
			sizeList.setSelectedValue(String.valueOf(fontSize), true);
		}
		else
		{
			sizeText.setText(String.valueOf(fontSize));
		}
		//选择字体列表中的某项
		fontList.setSelectedValue(fontName, true);
		//选择样式列表中的某项
		styleList.setSelectedIndex(fontStyle);
		//预览默认显示中文字符
		chinaButton.doClick();
		//显示预览
		setPreview();
	}
	//添加所需的事件监听器
	private void addListener() {
		sizeText.addFocusListener(new FocusListener() {
			public void focusLost(FocusEvent e) {
				setPreview();
			}
			public void focusGained(FocusEvent e) {
				sizeText.selectAll();
			}
		});
		//字体列表发生选择事件的监听器
		fontList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				if(!e.getValueIsAdjusting()) {
					fontText.setText(String.valueOf(fontList.getSelectedValue()));
					//设置预览
					setPreview();
				}
			}
		});
		styleList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				if(!e.getValueIsAdjusting()) {
					styleText.setText(String.valueOf(styleList.getSelectedValue()));
					setPreview();
				}
			}
		});
		sizeList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				if(!e.getValueIsAdjusting()) {
					if(!sizeText.isFocusOwner()) {
						sizeText.setText(String.valueOf(sizeList.getSelectedValue()));
					}
					//设置预览
					setPreview();
				}
			}
		});
		//编码监听器
		EncodeAction ea = new EncodeAction();
		chinaButton.addActionListener(ea);
		englishButton.addActionListener(ea);
		numberButton.addActionListener(ea);
		//确定按钮的事件监听
		approveButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			//组合字体
			font = groupFont();
			//设置返回值
			returnValue = APPROVE_OPTION;
			//关闭窗口
			disposeDialog();
			}
		});
		//取消按钮事件监听
		cancelButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				disposeDialog();
			}
		});
	}
	
	//显示字体选择器
	public final int showFontDialog(JFrame owner) {
		setLocationRelativeTo(owner);
		setVisible(true);
		return returnValue;
	}
	//返回选择的字体对象
	public final Font getSelectFont() {
		return font;
	}
	//关闭窗口
	private void disposeDialog() {
		MQFontChooser.this.removeAll();
		MQFontChooser.this.dispose();
	}
	//显示错误信息
	private void showErrorDialog(String errorMessage) {
		JOptionPane.showMessageDialog(this, errorMessage, "错误", JOptionPane.ERROR_MESSAGE);
	}
	//设置预览
	private void setPreview() {
		Font f = groupFont();
		previewText.setFont(f);
	}
	//按照选择组合字体
	private Font groupFont() {
		String fontName = fontText.getText();
		int fontStyle = styleList.getSelectedIndex();
		String sizeStr = sizeText.getText().trim();
		//如果没有输入
		if(sizeStr.length() == 0) {
			showErrorDialog("字体(大小)必须是有效“数值!");
			return null;
		}
		int fontSize = 0;
		//通过循环对比文字大小输入是否在现有列表内
		for(int i = 0; i < sizeArray.length; i++) {
			if(sizeStr.equals(sizeArray[i])) {
				fontSize = sizeIntArray[i];
				break;
			}
		}
		//没有在列表内
		if(fontSize == 0) {
			try {
				fontSize = Integer.parseInt(sizeStr);
				if(fontSize < 1) {
					showErrorDialog("字体(大小)必须是有效数值!");
					return null;
				}
			} catch (NumberFormatException nfe) {
				showErrorDialog("字体(大小)必须是有效数值!");
				return null;
			}
		}
		return new Font(fontName, fontStyle, fontSize);
	}
	//编码选择事件的监听动作
	class EncodeAction implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			if(e.getSource().equals(chinaButton)) {
				previewText.setText(CHINA_STRING);
			} else if(e.getSource().equals(englishButton)) {
				previewText.setText(ENGLISH_STRING);
			} else {
				previewText.setText(NUMBER_STRING);
			}
		}
	}
}

三、特点

1.行为动作监听直接添加到子菜单。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//子菜单添加监听器
public class My_Frame{
	public My_Frame(){
		itemNew.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				actionNew();
			}
		});
		itemOpen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionOpen();
			}
		});
		itemSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionSave();
			}
		});
		itemSaveAs.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atctionSaveAs();
			}
		});
	}
	public void actionNew(){
	}
	public void actionOpen(){
	}
	public void actionSave(){
	}
	public void actionSaveAs(){
	}
}
2.创建了一个内部时钟类Clock,一个行号显示类TestLine
3.引用了一个外部字体设置类MQFontChooser

##注意:

//textArea文本域设置滚动面板会有一个警告:
 Warning: the font “Times” is not available, so “Lucida Bright” has been substituted, but may have unexpected appearance or behavor. Re-enable the “Times” font to remove this warning.
 //创建滚动面板
 scrollpanel = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

参考文献