zoukankan      html  css  js  c++  java
  • Java实战_手把手编写记事本

    Java运用SWT插件编写桌面记事本应用程序

    可实现windows系统桌面记事本基本功能。傻瓜式教学,一步一步手把手操作。小白也可自己编写出完整的应用程序。


    须要工具:Eclipse(带SWT插件)
    成品例如以下:
    这里写图片描写叙述

    应用程序功能介绍:

    功能分析:
    1.文件(F)
    2.编辑(E)
    3.格式(O)
    4.查看(V)
    5.帮助(H)
    当中文件菜单中包含
    1.1.新建(N) Ctrl+N
    1.2打开(O) Ctrl+O
    1.3保存(S) Ctrl+S
    1.4另存为(A)
    1.5退出(X)
    当中编辑菜单中包含:
    2.1撤销(U) Ctrl+Z
    2.2剪切(T) Ctrl+T
    2.3复制(C) Ctrl+C
    2.4粘贴(P) Ctrl+V
    2.5删除(L) Del
    2.6查找(D) Ctrl+F
    2.7查找下一处(N) F3
    2.8替换(R) Ctrl+H
    2.9转到(G) Ctrl+G
    2.10全选(A) Ctrl+A
    2.11时间/日期(D) F5
    当中格式菜单中包含
    3.1自己主动换行(W)
    3.2字体(F)
    当中查看菜单中包含
    4.1状态栏(S)
    当中帮助菜单中包含
    5.1查看帮助(H)
    5.2关于记事本(A)
    接下来会一步一步教大家手把手编写一个记事本
    详细的几个类例如以下:
    1.NotePad.java
    该类为主界面类,当中包含了各个button的监听事件
    2.Util.java类
    该类为辅助类,方便在别的类中调用主窗体类中定义的成员
    3.AboutAuthor.java
    关于作者的类,一个Dialog窗体,用于显示作者信息
    4.FindWindow.java
    查找功能的一个Dialog窗体
    5.Go_To.java
    转到功能的一个Dialog窗体
    6.OpenMethod.java
    里面封装了打开文件的两个方法
    7.SavaMethod.java
    封装了保存文件的两种方法
    8.SWTResourceManager.java
    该类为外部导入的类。用于载入图片
    9.test.java
    程序入口,方便之后的打包程jar文件
    10.QuitMethod.java
    封装了关闭窗体的两种方法
    以上源码我都会提供下载地址

    编写步骤:

    一.新建SWT项目以及第一个窗体的创建

    打开Eclipse,new->other->WindowBuilder->SWT Designer->SWT/JFace Java Project .将project name 命名为 NotePad

    打开新建好的NotePadproject。在scr处右键 new->Package 新建一个包。命名为com.chance.org
    tips:包的命名规则,最好用com.自己定义.org ,别问为什么,以后工作了你就会明确了。
    右键新建好的包 new->other ->WindowBuilder->SWT Designer -> SWT ->Application Window 命名为NotePad
    到此,我们便建好了第一个SWT窗体点击source右边的design就可以查看新建号的图形界面。实现可视化编程。
    将NotePad窗体中属性(Properties)里的txt属性改名为:NotePad
    将Composites中的Composites组件拖入NotePad组件下,并将其Layout属性改动为FillLayout。即填充式布局,这样就可以方便后面将整个界面变成编辑域。

    接着将text组件拖入Composites组件下。

    将text组件的属性Style中的h_scroll属性以及v_scroll属性勾选为true
    说明:h_scroll为横向滚动栏,v_scroll为纵向滚动栏

    二.设置菜单条的相关标签以及窗体整体布局

    选择Menu bar组件 将其拖入主窗体中

    1.设置第一个菜单项(文件)

    选择Cascde Menu组件,将其拖入Menu bar组件中,改动属性:variable属性改动为file_menu, text改动为 文件(F);
    1.1设置子菜单:新建(N) Ctrl+N
    选择Menu Item加入到Cascde Menu组件下。改动属性:variable属性改动为new_file, text改动为:新建(N) Ctrl+N;
    1.2设置子菜单:打开(O) Ctrl+O
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为open_file, text改动为:打开(O) Ctrl+O
    1.3设置子菜单:保存(O) Ctrl+S
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为save_file, text改动为: 保存(O) Ctrl+S
    1.4设置子菜单:另存为(A)
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为save_as, text改动为: 另存为(A)
    1.5设置子菜单:退出(X)
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为quit, text改动为: 退出(X)

    2.设置第二个菜单项(编辑)

    选择Cascde Menu组件,将其拖入Menu bar组件中,改动属性:variable属性改动为edit_menu, text改动为 编辑(E);
    2.1设置子菜单:撤销(U) Ctrl+Z
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为undo, text改动为: 撤销(U) Ctrl+Z, 并将enable改为false;
    2.2设置子菜单:剪切(T) Ctrl+T
    选择Menu Item加入到Cascde Menu组件下。改动属性:variable属性改动为cut, text改动为: 剪切(T) Ctrl+T, 并将enable改为false;
    2.3设置子菜单:复制(C) Ctrl+C
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为copy, text改动为: 复制(C) Ctrl+C, 并将enable改为false;
    2.4设置子菜单:粘贴(P) Ctrl+V
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为paste, text改动为: 粘贴(P) Ctrl+V
    2.5设置子菜单:删除(L) Del
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为delete, text改动为: 删除(L) Del, 并将enable改为false;
    2.6设置子菜单:查找(D) Ctrl+F
    选择Menu Item加入到Cascde Menu组件下。改动属性:variable属性改动为find, text改动为: 查找(D) Ctrl+F, 并将enable改为false;
    2.7设置子菜单:查找下一处(N) F3
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为find_next, text改动为: 查找下一处(N) F3, 并将enable改为false;
    2.8设置子菜单:替换(R) Ctrl+H
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为replace, text改动为: 替换(R) Ctrl+H, 并将enable改为false;
    2.9设置子菜单:转到(G) Ctrl+G
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为go_to, text改动为: 转到(G) Ctrl+G
    2.10设置子菜单:全选(A) Ctrl+A
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为selectAll, text改动为: 全选(A) Ctrl+A
    2.11设置子菜单:时间/日期(D) F5
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为showDate, text改动为: 时间/日期(D) F5

    3.设置第三个菜单项(格式)

    选择Cascde Menu组件,将其拖入Menu bar组件中。改动属性:variable属性改动为format_menu, text改动为 格式(O);
    3.1设置子菜单:自己主动换行(W)
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为auto_Enter, text改动为: 自己主动换行(W)
    3.2设置子菜单:字体(F)
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为setFont, text改动为: 字体(F)

    4.设置第四个菜单项(查看)

    选择Cascde Menu组件。将其拖入Menu bar组件中,改动属性:variable属性改动为view_menu, text改动为 查看(V);
    4.1设置子菜单:状态栏(S)
    选择Menu Item加入到Cascde Menu组件下,改动属性:variable属性改动为state, text改动为: 状态栏(S)

    5.设置第五个菜单项(帮助)

    选择Cascde Menu组件,将其拖入Menu bar组件中。改动属性:variable属性改动为help_menu, text改动为 帮助(H);
    5.1设置子菜单:查看帮助(H)
    选择Menu Item加入到Cascde Menu组件下。改动属性:variable属性改动为lookHelp, text改动为: 查看帮助(H)
    5.2设置子菜单:关于记事本(A)
    选择Menu Item加入到Cascde Menu组件下。改动属性:variable属性改动为aboutAuthor, text改动为: 关于记事本(A)
    至此,已将整个页面布局设置完毕
    效果图例如以下:
    这里写图片描写叙述
    接下来实现各个功能

    三.设置菜单快捷键

    setAccelerator()函数的介绍:使用setAccelerator()函数设置相关的快捷键。传入的參数为键值
    比如快捷键Ctrl+N 设置方法为: 对象. setAccelerator(SWT.CTrl+’N’);
    快捷键F5 设置方法为:对象.setAccelerator(SWT.F5);
    由此我们能够将所需的所有快捷键设置出来

            new_file.setAccelerator(SWT.CTRL + 'N'); //新建文件快捷键
            open_file.setAccelerator(SWT.CTRL + 'O');//保存文件快捷键
            undo.setAccelerator(SWT.CTRL + 'Z');     //撤销快捷键
            cut.setAccelerator(SWT.CTRL + 'T');      //剪切快捷键
            copy.setAccelerator(SWT.CTRL + 'C');     //复制快捷键
            paste.setAccelerator(SWT.CTRL + 'V');    //粘贴快捷键
            delete.setAccelerator(SWT.DEL);          //删除快捷键
            find.setAccelerator(SWT.CTRL + 'F');     //查找快捷键
            find_next.setAccelerator(SWT.F3);        //查找下一处快捷键
            replace.setAccelerator(SWT.CTRL + 'H');  //替换快捷键
            go_to.setAccelerator(SWT.CTRL + 'G');    //转到快捷键
            selectAll.setAccelerator(SWT.CTRL + 'A');//全选快捷键
            showDate.setAccelerator(SWT.F5);         //显示时间快捷键

    四.加入事件监听函数(1)文件类

    为文件每一个菜单加入事件监听函数

    1.加入”退出” 菜单的监听事件

    功能描写叙述:触发该菜单将退出应用程序
    退出的实现比較简单,调用系统函数System.exit(0);就可以
    在design模式下点击”时间/日期(F5)”组件 再点击”Show event”->selection->双击widgetSelected
    事件代码例如以下:

    quit.addSelectionListener(new SelectionAdapter() {
                /**
                 * 加入"退出"菜单的监听事件
                 * 功能描写叙述:触发该菜单将退出应用程序
                 */
                public void widgetSelected(SelectionEvent e) {
                    System.exit(0);
                }
            });

    但事实真的这么简单吗,事实上不然,哪有点击退出就直接退出的,真正的记事本,退出的时候可是还有提示的。于是乎。改进后的代码例如以下。

    public void DIYquit(){
            /**
             * 退出函数退出时进行推断是否须要保存
             */
            String tips;
            System.out.println(Util.shell.getText().getText());
            if(Util.shell.fileDir != null || Util.shell.getText().getText() != ""){  //文件文件夹不为空,说明有打开着的文件,须要询问是否保存
                if(Util.shell.fileDir == null){
                    tips = "文件  无标题   的文字已经改变。
    "+"想保存文件吗";
                }else{
                    tips = "文件  " +Util.shell.fileDir + "  的文字已经改变。
    "+"想保存文件吗";
                }
                int n=JOptionPane.showConfirmDialog(null, tips,"记事本",JOptionPane.YES_NO_CANCEL_OPTION);
                if(n==0){  //是 返回0  否返回1 取消 返回2 
                    SaveMethod savemethod = new SaveMethod();
                    savemethod.Save(); //点是。则保存文件然后打开文件
                }else if(n==1){ //返回否
                    System.exit(0);
                }else if(n==2){  //返回取消
                    return ;
                }
                System.exit(0);
            }else{ 
                if(Util.shell.getText().getText() != ""){ //若文件夹为空。可是内容不为空。说明有内容但未保存。提示之
                    tips = "文件  无标题   的文字已经改变。
    "+"想保存文件吗";
                    int n=JOptionPane.showConfirmDialog(null, tips,"记事本",JOptionPane.YES_NO_CANCEL_OPTION);
                    if(n==0){  //是 返回0  否返回1 取消 返回2 
                        SaveMethod savemethod = new SaveMethod();
                        savemethod.Save(); //点是,则保存文件然后打开文件
                    }else if(n==1){ //返回否
                        System.exit(0);
                    }else if(n==2){  //返回取消
                        return ;
                    }
                    System.exit(0);
                }else{
    
                }
            }
            System.exit(0);
        }

    接下来的每一个监听事件内的操作我都定义为了一个函数,监听事件加入方法同第一步,详细实现方法例如以下:

    2. 加入”另存为” 菜单的监听事件

    功能描写叙述:触发该菜单将弹出另存为的窗体。实现将文件另存为别处
    这里为了方便代码的复用,另存为封装成方法进行调用
    代码例如以下:

    public void SaveAs(){
            /**
             * 将另存为这种方法进行封装,方便调用
             */
            FileDialog dialog = new FileDialog(Util.shell.shell,SWT.SAVE);
             dialog.setFilterPath(System.getProperty("C:\Documents and Settings"));//设置打开默认的路径
             dialog.setFilterExtensions(new String[] {"*.txt", "*.*"}); //设置所打开文件的扩展名
             dialog.setFilterNames( new String[]{"Text Files (*.txt)", "All Files (*.*)"}); //设置显示到下拉框中的扩展名的名称
             String file = dialog.open();//打开窗体。返回用户所选的文件文件夹
             if(file != null){
                 Util.shell.fileDir = file;//将文件文件夹保存下来,方面之后的使用
             }
             if ( file != null )
             {
                 Util.shell.shell.setText((new File( file.trim())).getName());//获取文件名称(不含路径)用于设置title
                FileWriter fileWriter;
                try {
                    fileWriter = new FileWriter(file);
                    BufferedWriter out = new BufferedWriter(fileWriter);
                    out.write(Util.shell.getText().getText());
                    out.close();
                    fileWriter.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
             }
        }

    3. 加入”保存” 菜单的监听事件

    功能描写叙述:触发”保存”菜单时。弹出保存文件窗体,然后选择文件夹和输入文件名称进行保存
    关于保存这里的逻辑我要好好说一说了:一開始一直在想怎样才干确定当前文档是否是保存还是另存为。后来细致观察桌面记事本才发现。原来保存和另存为弹出的对话框是同一个,仅仅须要略微加以差别就可推断是要保存还是要另存为了
    推断例如以下:若是保存则说明存在fileDir,直接调用保存的函数就可以,若不存在fileDir则说明文件时新打开的,还没确定过路径。因此跳转另存为窗体。
    首先定义一个全局变量String fileDir = null;将其赋值为空,默认所有的文件都未保存
    接着无论是打开文件,还是另存为文件,都将文件所在文件夹(包含文件名称以及后缀名)记录在fileDir中,最后在保存事件中确定fileDir是否为空就可以。
    代码例如以下:

        public void Save(){
    
            /**
             * 保存文件
             */
            if(Util.shell.fileDir!=null ){ //表示该文件有文件夹,保存时直接保存。不须要弹窗
                Util.shell.shell.setText((new File( Util.shell.fileDir.trim())).getName());//获取文件名称(不含路径)用于设置title
                FileWriter fileWriter;
                    try {
                        fileWriter = new FileWriter(Util.shell.fileDir);
                        BufferedWriter out = new BufferedWriter(fileWriter);
                        out.write(Util.shell.getText().getText());
                        out.close();
                        fileWriter.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
            }
            else{//否则为从未保存过,则调用另存为窗体
                SaveAs();
            }
        }

    4.加入”打开” 菜单的监听事件

    功能描写叙述:触发”打开”菜单时,弹出打开文件窗体,然后选择文件进行打开
    为了实现代码的复用。将打开方法进行封装成函数
    代码例如以下:

    public void OpenFile(){
            if(Util.shell.fileDir != null || Util.shell.getText().getText() != ""){
                String tips = "文件  " +Util.shell.fileDir + "  的文字已经改变。
    "+"想保存文件吗";
                int n=JOptionPane.showConfirmDialog(null, tips,"记事本",JOptionPane.YES_NO_CANCEL_OPTION);
                if(n==0){  //是 返回0  否返回1 取消 返回2 
                    SaveMethod savemethod = new SaveMethod();
                    savemethod.Save(); //点是,则保存文件然后打开文件
                }else if(n==1){ //返回否
    
                }else if(n==2){  //返回取消
                    return ;
                }
            }else{
                 FileDialog dialog = new FileDialog(Util.shell.shell,SWT.OPEN);
                 dialog.setFilterPath(System.getProperty("C:\Documents and Settings"));//设置打开默认的路径
                 dialog.setFilterExtensions(new String[] {"*.txt", "*.*"});//设置所打开文件的扩展名
                 dialog.setFilterNames( new String[]{"Text Files (*.txt)", "All Files (*.*)"});//设置显示到下拉框中的扩展名的名称
                 String file = dialog.open();//打开窗体,返回用户所选的文件文件夹(包含文件名称)
                 if(file == null){
                     return ;
                 }
                 Util.shell.fileDir = file;
                 Util.shell.shell.setText((new File( file.trim())).getName());//获取文件名称(不含路径)用于设置title
                  FileReader filereader;
                  try {
                    filereader = new FileReader(file);
                    BufferedReader in = new BufferedReader(filereader);
                    String s = null;
                    Util.shell.getText().setText(""); //将编辑框内容制空
                        try {
                            while((s=in.readLine())!=null){
                                Util.shell.getText().append(s+"
    ");
                            }
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                } catch (FileNotFoundException e2) {
                    e2.printStackTrace();
                }
            }
        }

    5. 加入”新建” 菜单的监听事件

    功能描写叙述:触发事件时,实现新建一个窗体,若当前文件未保存,提示其保存,否则跳转产生新页面。
    产生新页面的原理:将title又一次初始化。将fileDir初始化。以及把编辑域初始化就可以
    这里将打开新文件的代码抽出为一个方法。方便调用
    代码例如以下:

    void openNewFile() {
    
            if(Util.shell.fileDir != null || Util.shell.getText().getText() != ""){
                String tips = "文件  " +Util.shell.fileDir + "  的文字已经改变。

    "+"想保存文件吗"; int n=JOptionPane.showConfirmDialog(null, tips,"记事本",JOptionPane.YES_NO_CANCEL_OPTION); if(n==0){ //是 返回0 否返回1 取消 返回2 SaveMethod savemethod = new SaveMethod(); //点是,则保存文件然后打开文件 }else if(n==1){ //返回否 }else if(n==2){ //返回取消 return ; } String t = "无标题(" + ++Util.shell.cnt + ") - 记事本"; Util.shell.shell.setText(t); //设置标题 Util.shell.getText().setText(""); //清空编辑框 Util.shell.fileDir = null; }else{ String t = "无标题(" + ++Util.shell.cnt + ") - 记事本"; Util.shell.shell.setText(t); //设置标题 Util.shell.getText().setText(""); //清空编辑框 Util.shell.fileDir = null; } //所有的数据都初始化 }

    四.加入事件监听函数(2)编辑类

    为每一个菜单加入事件监听函数

    1.加入”显示时间”菜单的监听事件

    功能描写叙述:事件触发时,会在编辑框中光标所在处显示系统当时时间
    实现:获取当前系统时间,将其转换成String型。再调用text.append(str)方法。将时间显示在编辑框光标之后
    1.1加入事件监听函数
    获取系统当前时间方法:调用SimpleDateFormat对象格式化时间。再调用Date获取时间。


    刚開始存在的问题:每次都仅仅能加入到内容结尾。细致一想,必须要定位到当前光标所在位置。再将光标前的字符串+时间字符串+光标后的字符串 进行拼接,再一起显示出来。
    找了好久找到了getCaretPosition()刚好返回类型为整形。应该就是获取当前光标位置的,一试果然如此。接下来便是要实现字符串的拼接技术
    字符串拼接:s1.substring(0, index) + s2 + s1.substring(index, s1.length());
    返回的为新的字符串。
    出现的问题:拼接好后直接输出,导致之前存在的内容与后来新的字符串又一次拼接。改了好久才发现须要调用setText(String)方法,在输出之前先将之前编辑框中显示的内容清空
    终于监听函数内容例如以下:

        showDate.addSelectionListener(new SelectionAdapter() {
                /**
                 * 加入"时间日期"菜单的监听事件
                 * 功能描写叙述:触发该菜单将当前系统时间加入到编辑框光标结尾处
                 */
                public void widgetSelected(SelectionEvent e) {
                    int index = getText().getCaretPosition(); //获取当前编辑框中光标的位置
                    //System.out.println(index);
                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
                    String localTime = df.format(new Date());
                    String newString = insertString(getText().getText(),localTime,index); //拼接好后的字符串
                    getText().setText("");//将原来编辑框的内容清空再将新的内容显示出来
                    //System.out.println(localTime);// new Date()为获取当前系统时间
                    getText().append(newString); //将拼接好的字符串显示出来
                }
            });

    当中拼接字符串函数例如以下:

    public String insertString(String s1,String s2,int index){
            /**
             * 实现字符串的插入函数
             * 传入的三个參数为:原串。要插入的串,以及插入的位置
             * 返回的为插入后的字符串
             */
            return s1.substring(0, index) + s2 + s1.substring(index, s1.length());
        }

    2.加入”全选”菜单监听事件

    功能描写叙述:触发该菜单将所有选定文本域字符串
    Java里面的编辑框居然自带全选功能,哈哈。能够直接text.selectAll()调用,那预计复制和粘贴也有现成的,差点忘了,全选后还需推断所选内容是否为空。不为空则需将”删除” “剪切”这两个button设置成可选
    全选代码例如以下:

    selectAll.addSelectionListener(new SelectionAdapter() {
                    /**
                     * 加入"全选"菜单的监听事件
                     * 功能描写叙述:触发该菜单将所有选中文本域的文字,同一时候将"删除" "剪切"这两个button设置成可选
                     */
                    public void widgetSelected(SelectionEvent e) {
                        getText().selectAll(); //直接调用自带的函数哟
                        if(getText().getText() !=null){ //若内容不为空,说明全选有内容,因此须要将"删除" "剪切" "复制"这三个button设置成可选
                            delete.setEnabled(true); //将复制
                            cut.setEnabled(true);
                            copy.setEnabled(true);
                        }
                    }
                });

    3.加入”剪切”菜单监听事件

    功能描写叙述:触发该菜单,实现选择内容的剪切
    直接调用编辑框的cut()方法
    代码例如以下:

    cut.addSelectionListener(new SelectionAdapter() {
                    /**
                     * 加入"剪切"菜单的监听事件
                     * 功能描写叙述:触发该菜单将选中的字符串进行剪切
                     */
                    public void widgetSelected(SelectionEvent e) {
                        getText().cut();
                    }
                });

    4.加入”粘贴”菜单监听事件

    功能描写叙述:触发该菜单。实现将剪切板内容进行粘贴
    直接调用编辑框的paste()方法
    代码例如以下:

    paste.addSelectionListener(new SelectionAdapter() {
                    /**
                     * 加入"粘贴"菜单的监听事件
                     * 功能描写叙述:触发该菜单将剪切板中的内容粘贴到编辑框中
                     */
                    public void widgetSelected(SelectionEvent e) {
                        getText().paste();
                    }
                });

    5.加入”复制”菜单监听事件

    功能描写叙述:触发该菜单,实现将选择内容进行复制
    直接调用编辑框的copy()方法
    代码例如以下:

    copy.addSelectionListener(new SelectionAdapter() {
                /**
                 * 加入"剪切"菜单的监听事件
                 * 功能描写叙述:触发该菜单将选中的字符串进行剪切
                 */
                public void widgetSelected(SelectionEvent e) {
                    text.copy ();
                }
    

    6.加入”撤销”菜单监听事件

    功能描写叙述:触发该菜单,撤销当前步操作
    撤销该功能涉及到的算法长处复杂,临时该记事本不支持button的撤销方法。可是支持右键的撤销(右键的撤销时Java Text组件自带的。又不是我写的,哈哈)

    7.加入”查找”菜单监听事件

    功能描写叙述:触发该菜单,执行查找操作

                find.addSelectionListener(new SelectionAdapter() {
                    /**
                     * 加入查找功能的对话框。当中须要点击查找,然后弹出一个对话框。输入查找的相关内容
                     */
                    public void widgetSelected(SelectionEvent e) {
                        FindWindow fw = new FindWindow(shell,SWT.DIALOG_TRIM);
                        fw.open();
                    }  
                });

    四.加入事件监听函数(3)辅助类

    除了菜单条的几个菜单事件外。还须要监听键盘事件。即若有键盘键入文本域。则会触发相关菜单的显示:撤销,查找,查找下一处,替换 这四个菜单设置成可选

    1.文本域的监听

        getText().addKeyListener(new KeyAdapter() {
                    /**
                     * 设置键盘监听事件
                     * 有键盘键入则须要把相关button设置成可见:撤销,查找,查找下一处
                     */
                    public void keyReleased(KeyEvent e) {
                        if(getText().getText()!=""){//说明有输入
                            find.setEnabled(true);
                            find_next.setEnabled(true);
                            replace.setEnabled(true);
                        }else{
                            find.setEnabled(false);
                            find_next.setEnabled(false);
                            replace.setEnabled(true);
                        }
                    }
                });

    2.实现”字体”菜单的事件监听函数

    代码例如以下:

    setFont.addSelectionListener(new SelectionAdapter() {
                    /**
                     * 设置字体的监听事件
                     */
                    public void widgetSelected(SelectionEvent e) {
                        FontDialog fontDialog = new FontDialog(shell, SWT.NONE);
                        Font oldFont = getText().getFont();
                        if(oldFont != null) {
                            fontDialog.setFontList(oldFont.getFontData());
                        }
                        FontData fontData = fontDialog.open();
                        if(fontData == null) {
                            return;
                        }
                        final Display display = Display.getDefault();
                        Font newFont = new Font(display, fontData);
                        getText().setFont(newFont);
                        if(oldFont != null) {
                            oldFont.dispose();
                        }
                    }
                });

    五.窗体标签设置

    将主函数提取到test类,并将记事本的窗体的标题參数化。在主函数中传入一个初始标签:”无标题 – 记事本”
    

    在窗体类Main_Window中定义有參构造方法。传入的參数即为标题名
    构造函数例如以下:

        Main_Window(String titleName){
            /**
             * 有參构造传入的參数为文件名称
             */
            this.titleName = titleName;
        }

    注意的是:刚開始执行软件 标题为: 无标题 – 记事本
    打开文件时 标题为所打开的文件名称
    保存时 标题为所保存的文件名称
    另存为时 标题为另存为的文件名称
    已知路径获取文件名称(不包含路径)的方法为:
    shlNotepad.setText((new File( fileDir.trim())).getName());//获取文件名称(不含路径)用于设置title
    这里为了简洁我已经将其缩写成一句话代码

    设置了程序图标。将其放在project文件夹下,就可以直接引入使用

    思考:提示用户是否保存时,不能用仅仅看路径是否为空。应该要检測键盘是否有按下,即是否有改变。以及内容是否有改变(有可能直接右键删除,并未经过键盘)

    六.其它三个Dialog对话框的定义

    1.查找对话框

    相同右键新建好的包 new->other ->WindowBuilder->SWT Designer -> SWT ->Dialog命名为FindWindow
    成果图例如以下:
    这里写图片描写叙述
    这里查找,替换,以及查找下一处都共用这一个窗体。

    查找内容编辑框有内容方可触发button可点击。查找内容编辑框与替换为编辑框同一时候不为空方可触发替换功能
    这里列出查找下一处以及替换为的方法体
    查找下一处:
    思路:先获取主窗体中所有字符串,再获取须要查找的内容,直接调用Java 自带的查找字符串函数获得起始索引,再加上查找内容的字符串长度即为须要渲染的字符串长度,再调用主窗体中的渲染函数,将字符串进行渲染再显示出来。
    详细代码例如以下:

    find_next.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    pareStr = Util.shell.getText_1(); //获取主窗体文本框内容       true
                    index = pareStr.indexOf(textContent.getText(),index);  //获取查找串在母串中的从index处開始的位置
                    if(index == -1){
                        JOptionPane.showMessageDialog(null, "找不到""+textContent.getText()+""","记事本",  JOptionPane.ERROR_MESSAGE); 
                    }
                    int end = index+textContent.getText().length();//获得渲染的结束位置
                    Util.shell.selectContent(index, end);
                    index = index+textContent.getText().length();   
                }
            });

    替换button触发事件例如以下。

    replaceBtn.addSelectionListener(new SelectionAdapter() {
                /**
                 * 替换button事件
                 */
                public void widgetSelected(SelectionEvent e) {
                    pareStr = Util.shell.getText_1(); //获取主窗体文本框内容 
                    pareStr = pareStr.replaceFirst(textContent.getText(), replaceText.getText());
                    Util.shell.showText(pareStr);
                }
            });

    2.AboutAuthor对话框的建立

    该对话框的创建同查找对话框。将其命名为AboutAuthor就可以
    详细效果图例如以下:
    这里写图片描写叙述
    该对话框未涉及相关算法,加入三个JLabel标签然后输入三句话而已

    3.Go_to对话框的建立

    对话框建立方法不多说。命名为Go_to就可以
    详细效果图例如以下:
    这里写图片描写叙述
    代码实现例如以下:

    queding.addSelectionListener(new SelectionAdapter() {
                /**
                 * 确定跳转到某行
                 */
                public void widgetSelected(SelectionEvent e) {
                    int n = Integer.parseInt(goto_line.getText());
                    goto_line.setText(""+ n + "");
                    Util.shell.gotoOneLine(1);
                }
            });

    调用主窗体中的gotoOneLine()方法

        public void gotoOneLine(int row)
        {
            getText().setSelection(row);
        }

    至此,整个记事本的一般功能已所有完毕

    七.总结

    从刚開始编写,到终于的完毕,花了大概2-3天。当中学到了非常多相关的算法,Java编程非常方便,很多方法都不须要自己再去实现。直接调用就可以,可是Java也存在非常多不足,比方。关闭窗体的方法我用的Java自带的对话框,结果特别卡,各位感兴趣的能够自己定义退出的对话框,仅仅需将自带的三选对话框改成自己定义的对话框就可以。

    同一时候,前仅仅是出于学习。并未考虑到算法发高效性,比方打开文件操作,仅仅是实现了功能,但并未考虑算法的时效性,本例使用的方法是按行读取文件,你能够自己试试打开一个上千行的文本文档,你就能感认为到算法的重要性,还有就是 向上查找并未实现。初步思路:找到须要查找的坐标找到。然后从查找的坐标的位置開始往回走。将查找内容也倒置,再调用Java自带的字符串查找函数。
    比如:
    母串为 “ab记事本def3g” 须要从”3”这个字符串開始向前查找”记事本”字符串,可将母串中”3”字符串所在位置之前的字符串”ab记事本def”全然倒置为”g3fed本事记ba” 将查找内容也倒置成”本事记” 再调用Java内带的字符串查找函数查找所在位置。再还原就可以。


    当中撤销操作并未能实现,撤销算法逻辑并未能搞得清楚,还须要一段时间的探索,也欢迎感兴趣的朋友私信我或者给我留言告诉我详细的实现方法
    完整project代码下载地址:
    点我传送

  • 相关阅读:
    [再寄小读者之数学篇](2014-07-17 一阶中值)
    对流体力学做出巨大贡献的杰出历史人物
    理科生毁灭世界
    [再寄小读者之数学篇](2014-07-17 行列式的计算)
    [再寄小读者之数学篇](2014-07-16 高阶导数的一个表达式)
    [再寄小读者之数学篇](2014-07-16 与对数有关的不等式)
    [再寄小读者之数学篇](2014-07-16 凹函数与次线性性)
    [再寄小读者之数学篇](2014-07-16 二阶中值)
    [再寄小读者之数学篇](2014-07-16 任意阶导数在零处为零的一个充分条件)
    对PostgreSQL xmin的深入学习
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/8426351.html
Copyright © 2011-2022 走看看