java的swing编写读取文件指定后缀的内容的工具

问题描述:读取项目中后缀为java文件中的代码里的中文,也就是过滤注释里的中文,输出代码里的中文到本地文件里。

首先搭建一个框架,因为是工具,因此有一个可视化界面,界面有两个按钮,一个打开本地文件,一个导出到本地。当点击打开本地文件时候,会将选择的文件夹下的所有后缀为java的代码中的中文输出到界面。导出的时候可以选择导出到哪里,文件名为test.txt。

先搭建页面

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.MalformedInputException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;

public class Tool {
    JFrame window;
    JPanel panel,panel1,panel2;
    JButton btn1,btn2;
    JTextArea textArea;
    JScrollPane scrollPane;//文本域放入滚动窗口

    public Tool(String title){
        initUi(title);
    }
    
    public static void main(String[] args) {
        new Tool("我的窗口");
    }

    public void initUi(String title){

        window = new JFrame(title);
        panel = new JPanel();

        panel1 = new JPanel();
        //创建打开本地文件的按钮
        btn1 = new JButton("打开文件");
        btn1.setPreferredSize(new Dimension(100, 40));
        
        //添加按钮监控事件
        btn1.addActionListener(new button1ActionListener());
        //设置按钮区域的边框属性
        panel1.setBorder(BorderFactory.createTitledBorder("选择"));
        panel1.add(btn1);

        //创建导出按钮
        btn2 = new JButton("导出");
        btn2.setPreferredSize(new Dimension(100, 40));
        //添加按钮监控事件
        btn2.addActionListener(new button2ActionListener());
        panel1.add(btn2);

        panel2 = new JPanel();
        textArea = new JTextArea("中文汉字有:",20,100);
        textArea.setLineWrap(true);//自动换行
        textArea.setEditable(false);//设置文本框是否可编辑
        textArea.setForeground(Color.BLACK);
        textArea.setFont(new Font("楷体",Font.BOLD,16));//设置字体样式
        Dimension size = textArea.getPreferredSize();//获得文本域的首选大小
        //设置文本域滚动框
        scrollPane = new JScrollPane(textArea);
        scrollPane.setBounds(110,90,size.width,size.height);
        //设置文本区域的边框属性
        panel2.setBorder(BorderFactory.createTitledBorder("内容"));
        panel2.add(scrollPane);

        panel.setLayout(new BorderLayout());//设置布局为BorderLayout
        panel.add(panel1,BorderLayout.NORTH);
        panel.add(panel2,BorderLayout.CENTER);

        window.add(panel);
        //设置窗口大小
        window.setSize(1000,700);
        //居中
        window.setLocationRelativeTo(null);
        //设置窗口可见
        window.setVisible(true);
        window.setDefaultCloseOperation(DISPOSE_ON_CLOSE);//设置关闭方式
    }
    
}

注意上面的两句代码,给按钮添加监控事件,也就是点击之后做什么操作,后面的是内部类,接下来编写内部类的部分。

//添加打开文件按钮监控事件
btn1.addActionListener(new button1ActionListener());
//添加导出按钮监控事件
btn2.addActionListener(new button2ActionListener());

先编写打开文件按钮的内部类

//处理打开按钮单击事件的匿名内部类
class button1ActionListener implements ActionListener
{
    @Override
    public void actionPerformed(ActionEvent actionEvent)
    {
        //默认打开的位置是D盘下的文件
        JFileChooser fc = new JFileChooser(new File("D:\\"));
        //可以选择文件和目录,也就是用户打开点击可以选择的内容
        fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 
        fc.showOpenDialog(null); //文件打开对话框
		//获得用户选择的路径            
        String fileName = fc.getSelectedFile().getPath();
        //执行判断方法,将内容输出到textArea
        try {
            isPrint(fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public void isPrint(String fileName) throws IOException{
        try {
            StringBuffer sb = new StringBuffer();
            //用这个api来循环读取总文件下的所有文件
            Stream<Path> paths = Files.walk(Paths.get(fileName));
            //找出后缀为java的文件存放到list集合中
            List<String> result = paths.map(x->x.toString()).filter(f->f.endsWith(".java")).collect(Collectors.toList());
            for (String s:result){
                	//在控制台输出后缀为java文件的路径
                    System.out.println(s);
                try{
                    //用这个api读每个后缀为java文件的内容,存放到list集合中,按行读取
                    List<String> lines = Files.readAllLines(Paths.get(s), Charset.forName("UTF-8"));
                    for (String l:lines){
                        //第一层过滤,过滤不是中文的行,包括注释。因为第二层之间过滤了所有的带*的,带\的,这里就不做处理了
                        /*if (isChinese(l)){
                            System.out.println(l);
                        }*/

                        //第二层过滤,去除注释行,带*带/的中文行,用正则表达式过滤
                        if (isContainChinese(l)){
                            //第三层,去除log,logger的行,因为我的要求是要去除打印到日志里的中文行,这里也过滤掉
                            if (!l.contains("log")){
                                //找出""之间的内容
                                Pattern p = Pattern.compile("\".*[\u4e00-\u9fa5|%].*\"");
                                Matcher m = p.matcher(l);
                                //第四层提取出一行带有冒号的字符,因为中文都是在冒号里,所以提取出冒号里的东西
                                if(m.find()){
                                    //打印到控制台,发现不仅带冒号的中文打印出来了,而且英文的也打印出来了,这里写正则不好判断,因为中文里面也夹杂着英文,因此用逗号分割一下,在判断一下
                                   System.out.println(m.group());
                                   String[] split = m.group().split(",");
                                   for (String s2:split){
                                       if (isChinese(s2)){
                                           System.out.println(s2);
                                           //将过滤结果放入到sb里
                                           sb.append(s2.toString());
                                           sb.append("\n");
                                       }
                                   }
                                }
                            }
                                
                        }

                    }
                }catch (MalformedInputException e){
                    e.getMessage();
                }
            }
            //将过滤的内容添加到界面上	
            textArea.setText(sb.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

处理判断的两个静态方法

//判断出中文行带*的带/的,也就是注释行
public static boolean isContainChinese(String str) {
    Pattern p = Pattern.compile("^[^*/]*[\u4e00-\u9fa5]+[^*/]*$");
    Matcher m = p.matcher(str);
    return m.find();
}
//找出中文的
public static boolean isChinese(String str){
    Pattern p = Pattern.compile("[\u4e00-\u9fa5]+");
    Matcher m = p.matcher(str);
    return m.find();
}

在来编写导出按钮的内部类

//处理导出按钮单击事件的匿名内部类
class button2ActionListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        BufferedWriter bw = null;
        String choosePath = null;
        String newPath=null;
        try {
            //弹出文件选择框
            JFileChooser jfc = new JFileChooser("D:\\");
            //仅仅显示目录
            jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int option = jfc.showSaveDialog(null);

            //选择保存
            if (option==JFileChooser.APPROVE_OPTION){
                choosePath = jfc.getSelectedFile().getPath();
                newPath = choosePath.concat("/test.txt");
                //获得选择的路径,创建test.txt文件
                new File(newPath);
            }
            FileOutputStream os = new FileOutputStream(newPath);
            bw = new BufferedWriter(new OutputStreamWriter(os));
            for (String value:textArea.getText().split("  ")){
                bw.write(value);
                bw.newLine(); //换行
            }
        } catch (FileNotFoundException ex) {
            throw new RuntimeException(ex);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }finally {
            if (bw != null){
                try {
                    bw.close();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }
    }
}

总结:
目前只能判断编码格式是UTF-8的,导出文件不能用户命名,只能选择位置。

遇到的问题:
打成jar问题,idea默认 添加artifacts的时候META-INF文件位置是在 src/main/java/META_INF/下创建目录,但是此目录(src/main/java/)已标记为Sources Root,仅编译;修改成resource资源下的就行。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值