Java开发记事本(完整版)

源代码和可执行jar包:http://download.csdn.net/download/zenglinshan/9866365

右键菜单图

打印图

设置背景颜色、字体样式、字体颜色图

显示行号和字数


主要代码

package com.sxt.nodepad.view;

import java.awt.BorderLayout;

public class NotepadMainFrame extends JFrame implements ActionListener{

    /**
     * 序列号
     */
    private static final long serialVersionUID = 8585210209467333480L;
    private JPanel contentPane;
    private JTextArea textArea;
    private JMenuItem itemOpen;
    private JMenuItem itemSave;
    
    //1:新建 
    //2:修改过
    //3:保存过的
    int flag=0;

    //当前文件名
    String currentFileName=null;
    
     PrintJob  p=null;//声明一个要打印的对象
     Graphics  g=null;//要打印的对象
    
    //当前文件路径
    String currentPath=null;
    
    //背景颜色
    JColorChooser jcc1=null;
    Color color=Color.BLACK;
    
    //文本的行数和列数
    int linenum = 1;
    int columnnum = 1;
    
    //撤销管理器
    public UndoManager undoMgr = new UndoManager(); 
    
    //剪贴板
    public Clipboard clipboard = new Clipboard("系统剪切板"); 
    
    private JMenuItem itemSaveAs;
    private JMenuItem itemNew;
    private JMenuItem itemPage;
    private JSeparator separator;
    private JMenuItem itemPrint;
    private JMenuItem itemExit;
    private JSeparator separator_1;
    private JMenu itemEdit;
    private JMenu itFormat;
    private JMenu itemCheck;
    private JMenu itemHelp;
    private JMenuItem itemSearchForHelp;
    private JMenuItem itemAboutNotepad;
    private JMenuItem itemUndo;
    private JMenuItem itemCut;
    private JMenuItem itemCopy;
    private JMenuItem itemPaste;
    private JMenuItem itemDelete;
    private JMenuItem itemFind;
    private JMenuItem itemFindNext;
    private JMenuItem itemReplace;
    private JMenuItem itemTurnTo;
    private JMenuItem itemSelectAll;
    private JMenuItem itemTime;
    private JMenuItem itemFont;
    private JMenuItem itemColor;
    private JMenuItem itemFontColor;
    private JCheckBoxMenuItem itemNextLine;
    private JScrollPane scrollPane;
    private JCheckBoxMenuItem itemStatement;
    private JToolBar toolState;
    public static JLabel label1;
    private JLabel label2;
    private JLabel label3;
    int length=0;
    int sum=0;
    
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    NotepadMainFrame frame = new NotepadMainFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    
    GregorianCalendar c=new GregorianCalendar();
    int hour=c.get(Calendar.HOUR_OF_DAY);
    int min=c.get(Calendar.MINUTE);
    int second=c.get(Calendar.SECOND);    
    private JPopupMenu popupMenu;
    private JMenuItem popM_Undo;
    private JMenuItem popM_Cut;
    private JMenuItem popM_Copy;
    private JMenuItem popM_Paste;
    private JMenuItem popM_Delete;
    private JMenuItem popM_SelectAll;
    private JMenuItem popM_toLeft;
    private JMenuItem popM_showUnicode;
    private JMenuItem popM_closeIMe;
    private JMenuItem popM_InsertUnicode;
    private JMenuItem popM_RestartSelect;
    private JSeparator separator_2;
    private JSeparator separator_3;
    private JSeparator separator_4;
    private JSeparator separator_5;
    private JMenuItem itemRedo;
    private JSeparator separator_6;
    private JSeparator separator_7;
    private JSeparator separator_8;
    private JMenuItem popM_Redo;

    /**
     * Create the frame.
     */
    public NotepadMainFrame() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException e1) {
            e1.printStackTrace();
        } catch (InstantiationException e1) {
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
            e1.printStackTrace();
        } catch (UnsupportedLookAndFeelException e1) {
            e1.printStackTrace();
        }
        setTitle("无标题");    
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        setBounds(100, 100, 521, 572);
        
        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);
        
        JMenu itemFile = new JMenu("文件(F)");
        itemFile.setMnemonic('F');
        menuBar.add(itemFile);
        
        itemNew = new JMenuItem("新建(N)",'N');
        itemNew.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N,
                java.awt.Event.CTRL_MASK));  
        itemNew.addActionListener(this);
        itemFile.add(itemNew);
        
        itemOpen = new JMenuItem("打开(O)",'O');
        itemOpen.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O,
                            java.awt.Event.CTRL_MASK));  
        itemOpen.addActionListener(this);
        itemFile.add(itemOpen);
        
        itemSave = new JMenuItem("保存(S)");
        itemSave.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S,
                java.awt.Event.CTRL_MASK));   
        itemSave.addActionListener(this);
        itemFile.add(itemSave);
        
        itemSaveAs = new JMenuItem("另存为(A)");
        itemSaveAs.addActionListener(this);
        itemFile.add(itemSaveAs);
        
        separator = new JSeparator();
        itemFile.add(separator);
        
        itemPage = new JMenuItem("页面设置(U)",'U');
        itemPage.addActionListener(this);
        itemFile.add(itemPage);
        
        itemPrint = new JMenuItem("打印(P)...",'P');
        itemPrint.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P,
                java.awt.Event.CTRL_MASK));   
        itemPrint.addActionListener(this);
        itemFile.add(itemPrint);
        
        separator_1 = new JSeparator();
        itemFile.add(separator_1);
        
        itemExit = new JMenuItem("退出(X)",'X');
        itemExit.addActionListener(this);
        itemFile.add(itemExit);
        
        itemEdit = new JMenu("编辑(E)");
        itemEdit.setMnemonic('E');
        menuBar.add(itemEdit);
        
        itemUndo = new JMenuItem("撤销(U)",'U');
        itemUndo.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z,
                java.awt.Event.CTRL_MASK));
        itemUndo.addActionListener(this);
        itemEdit.add(itemUndo);
        
        itemRedo = new JMenuItem("恢复(R)");
        itemRedo.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R,
                java.awt.Event.CTRL_MASK));
        itemRedo.addActionListener(this);
        itemEdit.add(itemRedo);
        
        itemCut = new JMenuItem("剪切(T)",'T');
        itemCut.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X,
                java.awt.Event.CTRL_MASK));
        itemCut.addActionListener(this);
        
        separator_6 = new JSeparator();
        itemEdit.add(separator_6);
        itemEdit.add(itemCut);
        
        itemCopy = new JMenuItem("复制(C)",'C');
        itemCopy.addActionListener(this);
        itemCopy.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C,
                java.awt.Event.CTRL_MASK));
        itemEdit.add(itemCopy);
        
        itemPaste = new JMenuItem("粘贴(P)",'P');
        itemPaste.addActionListener(this);
        itemPaste.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V,
                java.awt.Event.CTRL_MASK));
        itemEdit.add(itemPaste);
        
        itemDelete = new JMenuItem("删除(L)",'L');
        itemDelete.addActionListener(this);
        itemDelete.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D,  
                InputEvent.CTRL_MASK));  
        itemEdit.add(itemDelete);
        
        separator_7 = new JSeparator();
        itemEdit.add(separator_7);
        
        itemFind = new JMenuItem("查找(F)",'F');
        itemFind.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F,
                Event.CTRL_MASK));
        itemFind.addActionListener(this);
        itemEdit.add(itemFind);
        
        itemFindNext = new JMenuItem("查找下一个(N)",'N');
        itemFindNext.setAccelerator(KeyStroke.getKeyStroke("F3"));
        itemFindNext.addActionListener(this);
        itemEdit.add(itemFindNext);
        
        itemReplace = new JMenuItem("替换(R)",'R');
        itemReplace.addActionListener(this);
        itemReplace.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H,
                Event.CTRL_MASK));
        itemEdit.add(itemReplace);
        
        itemTurnTo = new JMenuItem("转到(G)",'G');
        itemTurnTo.addActionListener(this);
        itemTurnTo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G,
                Event.CTRL_MASK));
        itemEdit.add(itemTurnTo);
        
        itemSelectAll = new JMenuItem("全选(A)",'A');
        itemSelectAll.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A,
                java.awt.Event.CTRL_MASK));
        itemSelectAll.addActionListener(this);
        
        separator_8 = new JSeparator();
        itemEdit.add(separator_8);
        itemEdit.add(itemSelectAll);
        
        itemTime = new JMenuItem("时间/日期(D)",'D');
        itemTime.addActionListener(this);
        itemTime.setAccelerator(KeyStroke.getKeyStroke("F5"));
        itemEdit.add(itemTime);
        
        itFormat = new JMenu("格式(O)");
        itFormat.setMnemonic('O');
        menuBar.add(itFormat);
        
        itemNextLine = new JCheckBoxMenuItem("自动换行(W)");
        itemNextLine.addActionListener(this);
        itFormat.add(itemNextLine);
        
        itemFont = new JMenuItem("字体大小(F)...");
        itemFont.addActionListener(this);
        itFormat.add(itemFont);
        
        itemColor = new JMenuItem("背景颜色(C)...");
        itemColor.addActionListener(this);
        itFormat.add(itemColor);
        
        itemFontColor = new JMenuItem("字体颜色(I)...");
        itemFontColor.addActionListener(this);
        itFormat.add(itemFontColor);
        
        itemCheck = new JMenu("查看(V)");
        itemCheck.setMnemonic('V');
        menuBar.add(itemCheck);
        
        itemStatement = new JCheckBoxMenuItem("状态栏(S)");
        itemStatement.addActionListener(this);
        itemCheck.add(itemStatement);
        
        itemHelp = new JMenu("帮助(H)");
        itemHelp.setMnemonic('H');
        menuBar.add(itemHelp);
        
        itemSearchForHelp = new JMenuItem("查看帮助(H)",'H');
        itemSearchForHelp.addActionListener(this);
        itemHelp.add(itemSearchForHelp);
        
        itemAboutNotepad = new JMenuItem("关于记事本(A)",'A');
        itemAboutNotepad.addActionListener(this);
        itemHelp.add(itemAboutNotepad);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        //设置边框布局
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);
        
        textArea = new JTextArea();
        
        //VERTICAL垂直    HORIZONTAL水平
        scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        
        //contentPane2=new JPanel();
        //contentPane2.setSize(10,textArea.getSize().height);
        //contentPane.add(contentPane2, BorderLayout.WEST);
        TestLine view = new TestLine();
        scrollPane.setRowHeaderView(view);
        
        popupMenu = new JPopupMenu();
        addPopup(textArea, popupMenu);
        
        popM_Undo = new JMenuItem("撤销(U)");
        popM_Undo.addActionListener(this);
        popupMenu.add(popM_Undo);
        
        popM_Redo = new JMenuItem("恢复(R)");
        popM_Redo.addActionListener(this);
        popupMenu.add(popM_Redo);
        
        separator_2 = new JSeparator();
        popupMenu.add(separator_2);
        
        popM_Cut = new JMenuItem("剪切(T)");
        popM_Cut.addActionListener(this);
        popupMenu.add(popM_Cut);
        
        popM_Copy = new JMenuItem("复制(C)");
        popM_Copy.addActionListener(this);
        popupMenu.add(popM_Copy);
        
        popM_Paste = new JMenuItem("粘贴(P)");
        popM_Paste.addActionListener(this);
        popupMenu.add(popM_Paste);
        
        popM_Delete = new JMenuItem("删除(D)");
        popM_Delete.addActionListener(this);
        popupMenu.add(popM_Delete);
        
        separator_3 = new JSeparator();
        popupMenu.add(separator_3);
        
        popM_SelectAll = new JMenuItem("全选(A)");
        popM_SelectAll.addActionListener(this);
        popupMenu.add(popM_SelectAll);
        
        separator_4 = new JSeparator();
        popupMenu.add(separator_4);
        
        popM_toLeft = new JMenuItem("从右到左的阅读顺序(R)");
        popM_toLeft.addActionListener(this);
        popupMenu.add(popM_toLeft);
        
        popM_showUnicode = new JMenuItem("显示Unicode控制字符(S)");
        popM_showUnicode.addActionListener(this);
        popupMenu.add(popM_showUnicode);
        
        popM_InsertUnicode = new JMenuItem("插入Unicode控制字符(I)");
        popM_InsertUnicode.addActionListener(this);
        popupMenu.add(popM_InsertUnicode);
        
        separator_5 = new JSeparator();
        popupMenu.add(separator_5);
        
        popM_closeIMe = new JMenuItem("关闭IME(L)");
        popM_closeIMe.addActionListener(this);
        popupMenu.add(popM_closeIMe);
        
        popM_RestartSelect = new JMenuItem("汉字重选(R)");
        popM_RestartSelect.addActionListener(this);
        popupMenu.add(popM_RestartSelect);
        //添加到面板中【中间】
        contentPane.add(scrollPane, BorderLayout.CENTER);
        
        //添加撤销管理器
        textArea.getDocument().addUndoableEditListener(undoMgr);
                
        
        toolState = new JToolBar();
        toolState.setSize(textArea.getSize().width, 10);//toolState.setLayout(new FlowLayout(FlowLayout.LEFT));
        label1 = new JLabel("    当前系统时间:" + hour + ":" + min + ":" + second+" ");
        toolState.add(label1);
        toolState.addSeparator();
        label2 = new JLabel("    第 " + linenum + " 行, 第 " + columnnum+" 列  ");
        toolState.add(label2);
        toolState.addSeparator();
        
        label3 = new JLabel("    一共 " +length+" 字  ");
        toolState.add(label3);
        textArea.addCaretListener(new CaretListener() {        //记录行数和列数
            public void caretUpdate(CaretEvent e) {
                //sum=0;
                JTextArea editArea = (JTextArea)e.getSource();
 
                try {
                    int caretpos = editArea.getCaretPosition();
                    linenum = editArea.getLineOfOffset(caretpos);
                    columnnum = caretpos - textArea.getLineStartOffset(linenum);
                    linenum += 1;
                    label2.setText("    第 " + linenum + " 行, 第 " + (columnnum+1)+" 列  ");
                    //sum+=columnnum+1;
                    //length+=sum;
                    length=NotepadMainFrame.this.textArea.getText().toString().length();
                    label3.setText("    一共 " +length+" 字  ");
                }
                catch(Exception ex) { }
            }});
        
        contentPane.add(toolState, BorderLayout.SOUTH);
        toolState.setVisible(false);
        toolState.setFloatable(false);
        Clock clock=new Clock();
        clock.start();
        
        
        
        // 创建弹出菜单
        final JPopupMenu jp=new JPopupMenu();    //创建弹出式菜单,下面三项是菜单项
        textArea.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(e.getButton()==MouseEvent.BUTTON3)//只响应鼠标右键单击事件
                {
                    jp.show(e.getComponent(),e.getX(),e.getY());//在鼠标位置显示弹出式菜单
                }
            }
        });
        
        isChanged();

        this.MainFrameWidowListener();
    }

    
    /*===============================1====================================*/
    /**
     * 是否有变化
     */
    private void isChanged() {
        textArea.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent e) {
                //在这里我进行了对使用快捷键,但是没有输入字符却没有改变textArea中内容的判断
                Character c=e.getKeyChar();
                if(c != null && !textArea.getText().toString().equals("")){
                    flag=2;
                }
            }
        });
    }
    /*===================================================================*/
    
    
    /*===============================2====================================*/
    /**
     * 新建的或保存过的退出只有两个选择
     */
    private void MainFrameWidowListener() {
        this.addWindowListener(new WindowAdapter(){
            @Override
            public void windowClosing(WindowEvent e) {
                if(flag==2 && currentPath==null){
                    //这是弹出小窗口
                    //1、(刚启动记事本为0,刚新建文档为1)条件下修改后
                    int result=JOptionPane.showConfirmDialog(NotepadMainFrame.this, "是否将更改保存到无标题?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
                    if(result==JOptionPane.OK_OPTION){
                        NotepadMainFrame.this.saveAs();
                    }else if(result==JOptionPane.NO_OPTION){
                        NotepadMainFrame.this.dispose();
                        NotepadMainFrame.this.setDefaultCloseOperation(EXIT_ON_CLOSE);
                    }
                }else if(flag==2 && currentPath!=null){
                    //这是弹出小窗口
                    //1、(刚启动记事本为0,刚新建文档为1)条件下修改后
                    int result=JOptionPane.showConfirmDialog(NotepadMainFrame.this, "是否将更改保存到"+currentPath+"?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
                    if(result==JOptionPane.OK_OPTION){
                        NotepadMainFrame.this.save();
                    }else if(result==JOptionPane.NO_OPTION){
                        NotepadMainFrame.this.dispose();
                        NotepadMainFrame.this.setDefaultCloseOperation(EXIT_ON_CLOSE);
                    }
                }else{
                    //这是弹出小窗口
                    int result=JOptionPane.showConfirmDialog(NotepadMainFrame.this, "确定关闭?", "系统提示", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE);
                    if(result==JOptionPane.OK_OPTION){
                        NotepadMainFrame.this.dispose();
                        NotepadMainFrame.this.setDefaultCloseOperation(EXIT_ON_CLOSE);
                    }
                }
            }
        });
    }
    /*===================================================================*/
    
    
    /*==============================3=====================================*/
    /**
     * 行为动作
     */
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==itemOpen){            //打开
            openFile();
        }else if(e.getSource()==itemSave){        //保存
            //如果该文件是打开的,就可以直接保存
            save();
        }else if(e.getSource()==itemSaveAs){    //另存为
            saveAs();
        }else if(e.getSource()==itemNew){        //新建
            newFile();
        }else if(e.getSource()==itemExit){        //退出
            exit();
        }else if(e.getSource()==itemPage){        //页面设置
            ///页面设置,百度到的,不知道具体的用法
            PageFormat pf = new PageFormat();
            PrinterJob.getPrinterJob().pageDialog(pf); 
        }else if(e.getSource()==itemPrint){        //打印
            //打印机
            Print();
        }else if(e.getSource()==itemUndo || e.getSource()==popM_Undo){        //撤销
            if(undoMgr.canUndo()){
                undoMgr.undo();
            }
        }else if(e.getSource()==itemRedo || e.getSource()==popM_Redo){        //恢复
            if(undoMgr.canRedo()){
                undoMgr.redo();
            }
        }else if(e.getSource()==itemCut || e.getSource()==popM_Cut){        //剪切
            cut();
        }else if(e.getSource()==itemCopy || e.getSource()==popM_Copy){        //复制
            copy();
        }else if(e.getSource()==itemPaste || e.getSource()==popM_Paste){    //粘贴
            paste();
        }else if(e.getSource()==itemDelete || e.getSource()==popM_Delete){    //删除
            String tem=textArea.getText().toString();
            textArea.setText(tem.substring(0,textArea.getSelectionStart())); 
        }else if(e.getSource()==itemFind){        //查找
            mySearch();
        }else if(e.getSource()==itemFindNext){    //查找下一个
            mySearch();
        }else if(e.getSource()==itemReplace){    //替换
            mySearch();
        }else if(e.getSource()==itemTurnTo){    //转到
            turnTo();
        }else if(e.getSource()==itemSelectAll || e.getSource()==popM_SelectAll){    //选择全部
            textArea.selectAll();
        }else if(e.getSource()==itemTime){        //时间/日期
            textArea.append(hour+":"+min+" "+c.get(Calendar.YEAR)+"/"+(c.get(Calendar.MONTH)+1)+"/"+c.get(Calendar.DAY_OF_MONTH));
        }else if(e.getSource()==itemNextLine){    //设置自动换行
            //设置文本区的换行策略。如果设置为 true,则当行的长度大于所分配的宽度时,将换行。此属性默认为 false。 
            if(itemNextLine.isSelected()){
                textArea.setLineWrap(true);
            }else{
                textArea.setLineWrap(false);
            }
        }else if(e.getSource()==itemFont){        //设置字体大小
            // 构造字体选择器,参数字体为预设值
            MQFontChooser fontChooser = new MQFontChooser(textArea.getFont());
            fontChooser.showFontDialog(this);
            Font font = fontChooser.getSelectFont();
            // 将字体设置到JTextArea中
            textArea.setFont(font);
        }else if(e.getSource()==itemColor){        //设置背景颜色
            jcc1 = new JColorChooser();
            JOptionPane.showMessageDialog(this, jcc1,"选择背景颜色颜色",-1);
            color = jcc1.getColor();
            textArea.setBackground(color);
        }else if(e.getSource()==itemFontColor){    //设置字体颜色
            jcc1=new JColorChooser();
            JOptionPane.showMessageDialog(this, jcc1, "选择字体颜色", -1);
            color = jcc1.getColor();
            //String string=textArea.getSelectedText();
            textArea.setForeground(color);
        }else if(e.getSource()==itemStatement){    //设置状态
            if(itemStatement.isSelected()){
                //scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
                toolState.setVisible(true);
            }else{
                //scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
                toolState.setVisible(false);
            }
        }else if(e.getSource()==itemSearchForHelp){
            JOptionPane.showMessageDialog(this, "赶快迷恋哥,趁哥还不是传说…","行动起来",1);
        }else if(e.getSource()==itemAboutNotepad){
            JOptionPane.showMessageDialog(this, "记事本V1.0【1603班zenglish制作】","软件说明 ",1);
        }
    }    
    /*===================================================================*/


    private void turnTo() {
        final JDialog gotoDialog = new JDialog(this, "转到下列行");
        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);
                    // System.out.println("引索pos:"+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(okButton);
        con.add(cancelButton);

        gotoDialog.setSize(200, 100);
        gotoDialog.setResizable(false);
        gotoDialog.setLocation(300, 280);
        gotoDialog.setVisible(true);
    }
    
    
    /*===============================8====================================*/
    /**
     * 推出按钮,和窗口的红叉实现一样的功能
     */
    private void exit() {
        if(flag==2 && currentPath==null){
            //这是弹出小窗口
            //1、(刚启动记事本为0,刚新建文档为1)条件下修改后
            int result=JOptionPane.showConfirmDialog(NotepadMainFrame.this, "是否将更改保存到无标题?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if(result==JOptionPane.OK_OPTION){
                NotepadMainFrame.this.saveAs();
            }else if(result==JOptionPane.NO_OPTION){
                NotepadMainFrame.this.dispose();
                NotepadMainFrame.this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            }
        }else if(flag==2 && currentPath!=null){
            //这是弹出小窗口
            //1、(刚启动记事本为0,刚新建文档为1)条件下修改后
            int result=JOptionPane.showConfirmDialog(NotepadMainFrame.this, "是否将更改保存到"+currentPath+"?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if(result==JOptionPane.OK_OPTION){
                NotepadMainFrame.this.save();
            }else if(result==JOptionPane.NO_OPTION){
                NotepadMainFrame.this.dispose();
                NotepadMainFrame.this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            }
        }else{
            //这是弹出小窗口
            int result=JOptionPane.showConfirmDialog(NotepadMainFrame.this, "确定关闭?", "系统提示", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE);
            if(result==JOptionPane.OK_OPTION){
                NotepadMainFrame.this.dispose();
                NotepadMainFrame.this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            }
        }
    }
    /*===================================================================*/


    /*===============================4====================================*/
    /**
     * 新建文件,只有改过的和保存过的需要处理
     */
    private void newFile() {
        if(flag==0 || flag==1){        //刚启动记事本为0,刚新建文档为1
            return;
        }else if(flag==2 && this.currentPath==null){        //修改后
            //1、(刚启动记事本为0,刚新建文档为1)条件下修改后
            int result=JOptionPane.showConfirmDialog(NotepadMainFrame.this, "是否将更改保存到无标题?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if(result==JOptionPane.OK_OPTION){
                this.saveAs();        //另存为                
            }else if(result==JOptionPane.NO_OPTION){
                this.textArea.setText("");
                this.setTitle("无标题");
                flag=1;
            }
            return;
        }else if(flag==2 && this.currentPath!=null ){
            //2、(保存的文件为3)条件下修改后
            int result=JOptionPane.showConfirmDialog(NotepadMainFrame.this, "是否将更改保存到"+this.currentPath+"?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if(result==JOptionPane.OK_OPTION){
                this.save();        //直接保存,有路径
            }else if(result==JOptionPane.NO_OPTION){
                this.textArea.setText("");
                this.setTitle("无标题");
                flag=1;
            }
        }else if(flag==3){        //保存的文件
            this.textArea.setText("");
            flag=1;
            this.setTitle("无标题");
        }
    }
    /*===================================================================*/
    
    
    /*===============================5====================================*/
    /**
     * 另存为
     */
    private void saveAs() {
        //打开保存框
        JFileChooser choose=new JFileChooser();
        //选择文件
        int result=choose.showSaveDialog(this);
        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;
                this.setTitle(currentPath);
            } catch (IOException e1) {
                e1.printStackTrace();
            }finally{
                try {
                    if(fw!=null) fw.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
    /*===================================================================*/
    

    /*===============================6====================================*/
    /**
     * 保存
     */
    private void save() {
        if(this.currentPath==null){
            this.saveAs();
            if(this.currentPath==null){
                return;
            }
        }
        FileWriter fw=null;
        //保存
        try {
            fw=new FileWriter(new  File(currentPath));
            fw.write(textArea.getText());
            //如果比较少,需要写
            fw.flush();
            flag=3;
            this.setTitle(this.currentPath);
        } catch (IOException e1) {
            e1.printStackTrace();
        }finally{
            try {
                if(fw!=null) fw.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }
    /*===================================================================*/
    
    
    /*================================7===================================*/
    /**
     * 打开文件
     */
    private void openFile() {
        if(flag==2 && this.currentPath==null){
            //1、(刚启动记事本为0,刚新建文档为1)条件下修改后
            int result=JOptionPane.showConfirmDialog(NotepadMainFrame.this, "是否将更改保存到无标题?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if(result==JOptionPane.OK_OPTION){
                this.saveAs();
            }
        }else if(flag==2 && this.currentPath!=null){
            //2、(打开的文件2,保存的文件3)条件下修改
            int result=JOptionPane.showConfirmDialog(NotepadMainFrame.this, "是否将更改保存到"+this.currentPath+"?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if(result==JOptionPane.OK_OPTION){
                this.save();
            }
        }
        //打开文件选择框
        JFileChooser choose=new JFileChooser();
        //选择文件
        int result=choose.showOpenDialog(this);
        if(result==JFileChooser.APPROVE_OPTION){
            //取得选择的文件
            File file=choose.getSelectedFile();
            //打开已存在的文件,提前将文件名存起来
            currentFileName=file.getName();
            //存在文件全路径
            currentPath=file.getAbsolutePath();
            flag=3;
            this.setTitle(this.currentPath);
            BufferedReader br=null;
            try {
                //建立文件流[字符流]
                InputStreamReader isr=new InputStreamReader(new FileInputStream(file),"GBK");
                br=new BufferedReader(isr);//动态绑定
                //读取内容
                StringBuffer sb=new StringBuffer();
                String line=null;
                while((line=br.readLine())!=null){
                    sb.append(line+SystemParam.LINE_SEPARATOR);
                }
                //显示在文本框[多框]
                textArea.setText(sb.toString());
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            } finally{
                try {
                    if(br!=null) br.close();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
    /*================================================================*/

    
    /*=============================9===================================*/
    public void Print()
    {
        try{
            p = getToolkit().getPrintJob(this,"ok",null);//创建一个Printfjob 对象 p
            g = p.getGraphics();//p 获取一个用于打印的 Graphics 的对象
            //g.translate(120,200);//改变组建的位置 
            this.textArea.printAll(g);
            p.end();//释放对象 g  
        }
        catch(Exception a){

        } 
    }
    /*================================================================*/
    
    
    private static void addPopup(Component component, final JPopupMenu popup) {
        component.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    showMenu(e);
                }
            }
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    showMenu(e);
                }
            }
            private void showMenu(MouseEvent e) {
                popup.show(e.getComponent(), e.getX(), e.getY());
            }
        });
    }
    
    public void cut(){
        copy();
        //标记开始位置
        int start = this.textArea.getSelectionStart();
        //标记结束位置
        int end = this.textArea.getSelectionEnd();
        //删除所选段
        this.textArea.replaceRange("", start, end);
        
    }
    
    public void copy(){
        //拖动选取文本
        String temp = this.textArea.getSelectedText();
        //把获取的内容复制到连续字符器,这个类继承了剪贴板接口
        StringSelection text = new StringSelection(temp);
        //把内容放在剪贴板
        this.clipboard.setContents(text, null);
    }
    
     public void paste(){
         //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();
             }
         }
     }
     
    public void mySearch() {
        final JDialog findDialog = new JDialog(this, "查找与替换", true);
        Container con = findDialog.getContentPane();
        con.setLayout(new FlowLayout(FlowLayout.LEFT));
        JLabel searchContentLabel = new JLabel("查找内容(N) :");
        JLabel replaceContentLabel = new JLabel("替换为(P)  :");
        final JTextField findText = new JTextField(22);
        final JTextField replaceText = new JTextField(22);
        final JCheckBox matchcase = new JCheckBox("区分大小写");
        ButtonGroup bGroup = new ButtonGroup();
        final JRadioButton up = new JRadioButton("向上(U)");
        final JRadioButton down = new JRadioButton("向下(D)");
        down.setSelected(true);
        bGroup.add(up);
        bGroup.add(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, b = 0, replaceCount = 0;

                if (findText.getText().length() == 0) {
                    JOptionPane.showMessageDialog(findDialog, "请填写查找内容!", "提示", JOptionPane.WARNING_MESSAGE);
                    findText.requestFocus(true);
                    return;
                }
                while (a > -1) {

                    int FindStartPos = textArea.getCaretPosition();
                    String str1, str2, str3, str4, strA, strB;
                    str1 = textArea.getText();
                    str2 = str1.toLowerCase();
                    str3 = findText.getText();
                    str4 = str3.toLowerCase();

                    if (matchcase.isSelected()) {
                        strA = str1;
                        strB = str3;
                    } else {
                        strA = str2;
                        strB = str4;
                    }

                    if (up.isSelected()) {
                        if (textArea.getSelectedText() == null) {
                            a = strA.lastIndexOf(strB, FindStartPos - 1);
                        } else {
                            a = strA.lastIndexOf(strB, FindStartPos - findText.getText().length() - 1);
                        }
                    } else if (down.isSelected()) {
                        if (textArea.getSelectedText() == null) {
                            a = strA.indexOf(strB, FindStartPos);
                        } else {
                            a = strA.indexOf(strB, FindStartPos - findText.getText().length() + 1);
                        }

                    }

                    if (a > -1) {
                        if (up.isSelected()) {
                            textArea.setCaretPosition(a);
                            b = findText.getText().length();
                            textArea.select(a, a + b);
                        } else if (down.isSelected()) {
                            textArea.setCaretPosition(a);
                            b = findText.getText().length();
                            textArea.select(a, a + b);
                        }
                    } 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("");
                        replaceCount++;
                    }
                    if (replaceText.getText().length() > 0 && textArea.getSelectedText() != null) {
                        textArea.replaceSelection(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()) {
                    if (textArea.getSelectedText() == null) {
                        a = strA.lastIndexOf(strB, FindStartPos - 1);
                    } else {
                        a = strA.lastIndexOf(strB, FindStartPos - findText.getText().length() - 1);
                    }
                } else if (down.isSelected()) {
                    if (textArea.getSelectedText() == null) {
                        a = strA.indexOf(strB, FindStartPos);
                    } else {
                        a = strA.indexOf(strB, FindStartPos - findText.getText().length() + 1);
                    }

                }
                if (a > -1) {
                    if (up.isSelected()) {
                        textArea.setCaretPosition(a);
                        b = findText.getText().length();
                        textArea.select(a, a + b);
                    } else if (down.isSelected()) {
                        textArea.setCaretPosition(a);
                        b = findText.getText().length();
                        textArea.select(a, a + b);
                    }
                } 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 direction = new JPanel();
        direction.setBorder(BorderFactory.createTitledBorder("方向 "));
        direction.add(up);
        direction.add(down);
        direction.setPreferredSize(new Dimension(170, 60));
        JPanel replacePanel = new JPanel();
        replacePanel.setLayout(new GridLayout(2, 1));
        replacePanel.add(replace);
        replacePanel.add(replaceAll);

        topPanel.add(searchContentLabel);
        topPanel.add(findText);
        topPanel.add(searchNext);
        centerPanel.add(replaceContentLabel);
        centerPanel.add(replaceText);
        centerPanel.add(replacePanel);
        bottomPanel.add(matchcase);
        bottomPanel.add(direction);
        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);
    }

}
4个工具类
package com.sxt.nodepad.util;

/**
 * 系统参数
 * @author Taylor
 *
 */
public class SystemParam {
	
	/**
	 * 当前系统换行符
	 */
	public static final String LINE_SEPARATOR=System.getProperty("line.separator");
}
package com.sxt.nodepad.util;

import java.util.Calendar;
import java.util.GregorianCalendar;

import com.sxt.nodepad.view.NotepadMainFrame;

public class Clock extends Thread{

	public void run() {
		while (true) {
			GregorianCalendar time = new GregorianCalendar();
			int hour = time.get(Calendar.HOUR_OF_DAY);
			int min = time.get(Calendar.MINUTE);
			int second = time.get(Calendar.SECOND);
			NotepadMainFrame.label1.setText("    当前时间:" + hour + ":" + min + ":" + second);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException exception) {
			}

		}
	}
}
package com.sxt.nodepad.util;

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;

/**
 * 这是自己找的一份字体选择器的资料
 * @author Taylor
 *
 */
public class MQFontChooser extends JDialog {
	/**
	 * 选择取消按钮的返回值
	 */
	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 = "Hello Kitty!";
	/**
	 * 数字预览的字符串
	 */
	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() {
		this(new Font("宋体", Font.PLAIN, 12));
	}
	/**
	 * 使用给定的预设字体构造一个字体选择器
	 * @param font 字体
	 */
	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.setMaximumSize(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(250, 95));
		box6.setMaximumSize(new Dimension(250, 95));
		box6.setMinimumSize(new Dimension(250, 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();
			}
		});
	}
	/**
	 * 显示字体选择器
	 * @param owner 上层所有者
	 * @return 该整形返回值表示用户点击了字体选择器的确定按钮或取消按钮,参考本类常量字段APPROVE_OPTION和CANCEL_OPTION
	 */
	public final int showFontDialog(JFrame owner) {
		setLocationRelativeTo(owner);
		setVisible(true);
		return returnValue;
	}
	/**
	 * 返回选择的字体对象
	 * @return 字体对象
	 */
	public final Font getSelectFont() {
		return font;
	}
	/**
	 * 关闭窗口
	 */
	private void disposeDialog() {
		MQFontChooser.this.removeAll();
		MQFontChooser.this.dispose();
	}
	
	/**
	 * 显示错误消息
	 * @param errorMessage 错误消息
	 */
	private void showErrorDialog(String errorMessage) {
		JOptionPane.showMessageDialog(this, errorMessage, "错误", JOptionPane.ERROR_MESSAGE);
	}
	/**
	 * 设置预览
	 */
	private void setPreview() {
		Font f = groupFont();
		previewText.setFont(f);
	}
	/**
	 * 按照选择组合字体
	 * @return 字体
	 */
	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);
			}
		}
	}
}

package com.sxt.nodepad.util;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;


public class TestLine extends javax.swing.JComponent {

    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;
    public final int MARGIN = 5;
    private int lineHeight;
    private int fontLineHeight;
    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));
        }
    }

    @Override
    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;
    }

    @Override
    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);
    }
}

 包图


总结

1、自动换行JTextArea有自己定义的策略。textArea.setLineWrap(true);
//设置文本区的换行策略。如果设置为 true,则当行的长度大于所分配的宽度时,将换行。此属性默认为 false。

2、字体样式设置需要自己新建一个类引入系统字体的样式包。

3、背景颜色:
JColorChooser jcc1 = new JColorChooser();
JOptionPane.showMessageDialog(this, jcc1,"选择背景颜色颜色",-1);
Color color = jcc1.getColor();
JTextArea textArea.setBackground(color);

4、字体颜色:
jcc1=new JColorChooser();
JOptionPane.showMessageDialog(this, jcc1, "选择字体颜色", -1);
Color color = jcc1.getColor();
JTextArea textArea.setForeground(color);

5、鼠标右击菜单:
// 创建弹出菜单
final JPopupMenu jp=new JPopupMenu();//创建弹出菜单,下面三项是菜单项
    JtextArea textArea.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        if(e.getButton()==MouseEvent.BUTTON3)//只响应鼠标右键单击事件
        {
            jp.show(e.getComponent(),e.getX(),e.getY());//在鼠标位置显示弹出式菜单
        }
    }
});

6、发现一个小问题,我打开保存过的文件,修改了一部分,然后按ctrl+s没有用,无论我退出还是新建、打开,都会提示我再保存。但是我在菜单上选择保存,就是正常的使用,这真有点奇怪。

7、大概30号的时候,我碰到一个问题,我在NotepadMainFrame类中,获取不到正确的保存路径,一直为Null,也就是我设置的默认值。后来封装到方法中就没有问题了,下次做项目的时候注意点。

8、打印功能:
public void Print()
{
    try{
        p = getToolkit().getPrintJob(this,"ok",null);//创建一个Printfjob 对象 p
    g = p.getGraphics();//p 获取一个用于打印的 Graphics 的对象
    //g.translate(120,200);//改变组建的位置
    this.textArea.printAll(g);
    p.end();//释放对象 g  
    }
    catch(Exception a){

    }
}

9、显示时间:用到了线程,每1秒刷新一次时间
public class Clock extends Thread{
    public void run() {
        while (true) {
        GregorianCalendar time = new GregorianCalendar();
        int hour = time.get(Calendar.HOUR_OF_DAY);
        int min = time.get(Calendar.MINUTE);
        int second = time.get(Calendar.SECOND);
        NotepadMainFrame.label1.setText("    当前时间:" + hour + ":" + min + ":" + second);
        try {
        Thread.sleep(1000);
            } catch (InterruptedException exception) {
            }
        }
    }
}
在NotepadMainFrame类中
JToolBar toolState = new JToolBar();
toolState.setSize(textArea.getSize().width, 10);//toolState.setLayout(new FlowLayout(FlowLayout.LEFT));
JLabel label1 = new JLabel("    当前系统时间:" + hour + ":" + min + ":" + second);
toolState.add(label1);
Clock clock=new Clock();
clock.start();

10、显示行数和列数:
label2 = new JLabel("    第 " + linenum + " 行, 第 " + columnnum+" 列  ");
toolState.add(label2);
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;
            label2.setText("    第 " + linenum + " 行, 第 " + (columnnum+1)+" 列  ");
        }
    catch(Exception ex) { }
}});
contentPane.add(toolState, BorderLayout.SOUTH);
toolState.setVisible(false);
toolState.setFloatable(false);

11、未完成的想法:(已实现)
在左侧添加显示的行数。

12、估计未完成的功能:
右键的菜单响应功能中的从右到左,Unicode码,汉字重选。
保存的文件设置了颜色和字体,打开后还是默认大小。
打印功能还可以再完善,现在只能打印一页多点,具体的设置还不是很懂,等我再多学点。
将自动换行和状态显示默认添加。

13、过程中发现自己对io流不熟悉,对API的使用更是不知道。

14、全选:就是用到了JTextArea的API    textArea.selectAll();
15、撤销、返回:初始化一个UndoManger,然后通过body.getDocument().addUndoableEditListener(undoMgr)这个方法,就可以把撤销管理器的监听器添加到TextArea中。需要调用撤销的时候就调用unoMgr.undo()方法。
UndoManager undoMgr=new UndoManager();
JtextArea textArea.getDocument().addUndoableEditListener(undoMgr);
if(undoMgr.canUndo()){
    undoMgr.undo();//撤销
}
if(undoMgr.canRedo()){
    undoMgr.redo();//恢复
}

16、程序基本完成了,有些地方可能功能不完善,以后如果有机会再修改吧。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页