zoukankan      html  css  js  c++  java
  • 使用原生Java代码生成可执行Jar包

      最近想做一个功能,就是把我们编译后的字节码及其资源文件打包成一个可执行的jar包,在装有jre的机器上双击就能运行。

      首先是我们需要选择哪些字节码和文件需要打包到文件中,这个我们用JFileChooser来做,让用户选择,我做了一个窗体来让用户选择。

      效果如下:

      

      我们让浏览文件系统,并选择需要打包的文件夹,然后计算出可以作为启动类的文件,通过下方的下拉让用户选择。

      生成文件路径在确认按钮点击后弹出文件保存框让用户选择就好(也可以弹出输入框)。

      代码如下:

      Main

     1 package org.coderecord.commons.ejarmaker;
     2 
     3 import java.awt.EventQueue;
     4 
     5 import javax.swing.UIManager;
     6 import javax.swing.UnsupportedLookAndFeelException;
     7 
     8 public class Main {
     9 
    10     public static void main(String[] args) {
    11         try {
    12             UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
    13         } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
    14             e.printStackTrace();
    15         }
    16         EventQueue.invokeLater(new Runnable() {
    17             
    18             @Override
    19             public void run() {
    20                 new FrmMain().setVisible(true);
    21             }
    22         });
    23     }
    24 
    25 }
    Main

      FrmMain(只是界面代码,业务代码最后贴出)

      1 package org.coderecord.commons.ejarmaker;
      2 
      3 import java.awt.Toolkit;
      4 import java.awt.event.ActionEvent;
      5 import java.awt.event.ActionListener;
      6 import java.io.File;
      7 import java.util.ArrayList;
      8 import java.util.List;
      9 
     10 import javax.swing.JButton;
     11 import javax.swing.JComboBox;
     12 import javax.swing.JFileChooser;
     13 import javax.swing.JFrame;
     14 import javax.swing.JLabel;
     15 import javax.swing.JScrollPane;
     16 import javax.swing.JTextArea;
     17 import javax.swing.filechooser.FileFilter;
     18 
     19 public class FrmMain extends JFrame implements ActionListener {
     20 
     21     private static final long serialVersionUID = 2016913328739206536L;
     22     // 选择的文件(用户在文件选择器中选择的)
     23     private List<File> userSelectedFiles = new ArrayList<>();
     24     // 我们经过分析得到的最终会被打包的文件
     25     private List<File> finalFiles = new ArrayList<>();
     26     
     27     public FrmMain() {
     28         setSize(480, 320);
     29         setResizable(false);
     30         setLocationRelativeTo(null);
     31         setTitle("通用可执行Jar包生成工具");
     32         setDefaultCloseOperation(EXIT_ON_CLOSE);
     33         setLayout(null);
     34         // 在运行时获取资源文件的方式,一定是使用Class.getResource方式
     35         // 在jar包中这种方式也行得通
     36         // ‘/’代表根路径
     37         setIconImage(Toolkit.getDefaultToolkit().getImage(FrmMain.class.getResource("/resources/icon.png")));
     38         initComponents();
     39     }
     40     
     41     // 初始化组件
     42     private void initComponents() {
     43         // 提示
     44         lblTip = new JLabel("选择需要打包的文件并设置启动类");
     45         lblTip.setLocation(20, 10);
     46         lblTip.setSize(350, 20);
     47         add(lblTip);
     48         
     49         // 浏览按钮
     50         btnBrowser = new JButton("浏 览");
     51         btnBrowser.setLocation(380, 10);
     52         btnBrowser.setSize(80, 24);
     53         btnBrowser.addActionListener(this);
     54         add(btnBrowser);
     55         
     56         // 展示已选择文件
     57         JScrollPane jspFiles = new JScrollPane();
     58         txtFiles = new JTextArea();
     59         txtFiles.setEditable(false);
     60         jspFiles.setSize(440, 160);
     61         jspFiles.setLocation(20, 40);
     62         txtFiles.setSize(440, 201600);
     63         txtFiles.setLocation(20, 40);
     64         txtFiles.setFocusable(false);
     65         jspFiles.setViewportView(txtFiles);
     66         add(jspFiles);
     67         
     68         // 选择启动类
     69         cobMainClass = new JComboBox<>();
     70         cobMainClass.setSize(440, 30);
     71         cobMainClass.setLocation(20, 210);
     72         add(cobMainClass);
     73         
     74         // 清除已选
     75         btnCls = new JButton("重 选");
     76         btnCls.setLocation(20, 250);
     77         btnCls.setSize(80, 24);
     78         btnCls.addActionListener(this);
     79         add(btnCls);
     80 
     81         // 确认按钮
     82         btnConfirm = new JButton("确认");
     83         btnConfirm.setSize(80, 24);
     84         btnConfirm.setLocation(380, 250);
     85         btnConfirm.addActionListener(this);
     86         add(btnConfirm);
     87         
     88         // 文件选择器
     89         jfcSelect = new JFileChooser();
     90         // 可以选择文件和文件夹
     91         jfcSelect.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
     92         // 可以多选
     93         jfcSelect.setMultiSelectionEnabled(true);
     94         
     95         // 文件保存
     96         jfcSave = new JFileChooser();
     97         // 设置只接受以“.jar”结尾的文件
     98         jfcSave.setAcceptAllFileFilterUsed(false);
     99         jfcSave.setFileFilter(new FileFilter() {
    100             
    101             @Override
    102             public String getDescription() {
    103                 return "可执行Jar";
    104             }
    105             
    106             @Override
    107             public boolean accept(File f) {
    108                 return f.getName().endsWith(".jar");
    109             }
    110         });
    111     }
    112 
    113     @Override
    114     public void actionPerformed(ActionEvent e) {
    115         
    116     }
    117     
    118     private JLabel lblTip;
    119     private JButton btnBrowser;
    120     private JFileChooser jfcSelect;
    121     private JTextArea txtFiles;
    122     private JComboBox<String> cobMainClass;
    123     private JButton btnCls;
    124     private JButton btnConfirm;
    125     private JFileChooser jfcSave;
    126 }
    FrmMain_UI

      然后开始业务部分,首先是选择文件,我们允许用户选择多个文件和文件夹(甚至可以通过多次选择来选择不同盘符、路径下的文件和文件夹),在选择后可能有重复的地方或两次选择后有包含的项目,我们要去除。

      我们为“浏览”按钮事件添加处理,让用户选择文件并处理选中文件:

      1 @Override
      2     public void actionPerformed(ActionEvent e) {
      3         if(e.getSource() == btnBrowser) {
      4             // 浏览
      5             int result = jfcSelect.showOpenDialog(this);
      6 
      7             // 选择了文件
      8             if(result == JFileChooser.APPROVE_OPTION) {
      9                 for(File file : jfcSelect.getSelectedFiles())
     10                     userSelectedFiles.add(file);
     11                 
     12                 // 整理选择的文件,去除重复项
     13                 removeDuplicateItems(userSelectedFiles);
     14                 
     15                 // 重新计算选中文件
     16                 finalFiles.clear();
     17                 for(File file : userSelectedFiles)
     18                     addFileToList(file, finalFiles);
     19                 
     20                 // 计算文件展示打包路径及展示路径
     21                 // 计算可启动类路径
     22                 // 展示到文本框中
     23                 cobMainClass.removeAllItems();
     24                 txtFiles.setText("");
     25                 File file,direc;
     26                 String filePath,direcPath;
     27                 Iterator<File> itd,itf;
     28                 for(itd = userSelectedFiles.iterator(); itd.hasNext();) {
     29                     direc = itd.next();
     30                     direcPath = direc.getAbsolutePath();
     31                     for(itf = finalFiles.iterator(); itf.hasNext();) {
     32                         file = itf.next();
     33                         filePath = file.getAbsolutePath();
     34                         if(filePath.equalsIgnoreCase(direcPath)) {
     35                             txtFiles.append(file.getName() + "
    ");
     36                             filePaths.put(file.getName(), file);
     37                             //fileNames.put(file.getName(), file.getName().endsWith(".class")?file.getName().substring(0, file.getName().lastIndexOf('.')):file.getName());
     38                             if(file.getName().endsWith(".class"))
     39                                 cobMainClass.addItem(file.getName().endsWith(".class")?file.getName().substring(0, file.getName().lastIndexOf('.')):file.getName());
     40                             itf.remove();
     41                         } else if(filePath.startsWith(direcPath)) {
     42                             String nameTmp = filePath.substring(direcPath.lastIndexOf(File.separator) + 1).replace(File.separatorChar, '/'); 
     43                             filePaths.put(nameTmp, file);
     44                             txtFiles.append(nameTmp + "
    ");
     45                             //fileNames.put(nameTmp, nameTmp.endsWith(".class")?nameTmp.substring(0, nameTmp.lastIndexOf('.')).replace('/', '.'):nameTmp);
     46                             if(nameTmp.endsWith(".class") && nameTmp.indexOf('$') == -1)
     47                                 cobMainClass.addItem(nameTmp.substring(0, nameTmp.lastIndexOf('.')).replace('/', '.'));
     48                             itf.remove();
     49                         }
     50                     }
     51                 }
     52             }
     53         }
     54     }
     55     
     56     // 添加文件(非文件夹)到集合
     57     private void addFileToList(File file, List<File> fileArr) {
     58         if(file.isDirectory())
     59             for(File child : file.listFiles())
     60                 addFileToList(child, fileArr);
     61         else
     62             fileArr.add(file);
     63     }
     64     
     65     // 去除重复项
     66     private void removeDuplicateItems(List<File> fileArr) {
     67         // 去重复项
     68         Set<String> directories = new HashSet<>();
     69         Set<String> files = new HashSet<>();
     70         for(File file : fileArr)
     71             if(file.isDirectory())
     72                 directories.add(file.getAbsolutePath());
     73             else
     74                 files.add(file.getAbsolutePath());
     75         //去包含项(先去文件夹再去文件应该更好)
     76         String fpath,dpath;
     77         for(Iterator<String> itf = files.iterator(); itf.hasNext();) {
     78             fpath = itf.next();
     79             for(Iterator<String> itd = directories.iterator(); itd.hasNext();) {
     80                 dpath = itd.next();
     81                 if(fpath.startsWith(dpath))
     82                     itf.remove();
     83             }
     84         }
     85         String dpath1,dpath2;
     86         Set<String> directories1 = new HashSet<>(directories);
     87         for(Iterator<String> itd1 = directories.iterator(); itd1.hasNext();) {
     88             dpath1 = itd1.next();
     89             for(Iterator<String> itd2 = directories1.iterator(); itd2.hasNext();) {
     90                 dpath2 = itd2.next();
     91                 if(dpath1.equals(dpath2))
     92                     continue;
     93                 else if(dpath2.startsWith(dpath1))
     94                     itd2.remove();
     95                 else if(dpath1.startsWith(dpath2))
     96                     itd1.remove();
     97             }
     98         }
     99         directories.addAll(directories1);
    100         
    101         fileArr.clear();
    102         for(String file : files)
    103             fileArr.add(new File(file));
    104         for(String directory : directories)
    105             fileArr.add(new File(directory));
    106     }
    btnBrowser_event_handler

      “重选”按钮点击后清除已选项,逻辑就先不详细介绍了。

      然后是“确定”按钮,我们弹出文件保存框让用户选择保存位置,然后生成可执行的jar包:

     1 @Override
     2     public void actionPerformed(ActionEvent e) {
     3         if(e.getSource() == btnBrowser) {
     4         } else if(e.getSource() == btnCls) {
     5             if(userSelectedFiles.size() == 0) return;
     6             else if(JOptionPane.showConfirmDialog(this, "确定重选吗?将清除所有已选项!") == JOptionPane.OK_OPTION) {
     7                 userSelectedFiles.clear();
     8                 finalFiles.clear();
     9                 filePaths.clear();
    10                 cobMainClass.removeAllItems();
    11             }
    12         } else if(e.getSource() == btnConfirm) {
    13             if(filePaths.size() == 0) {
    14                 JOptionPane.showMessageDialog(this, "未选择文件", "错误", JOptionPane.ERROR_MESSAGE);
    15                 return;
    16             } else if(cobMainClass.getSelectedItem() == null) {
    17                 JOptionPane.showMessageDialog(this, "未选择启动类", "错误", JOptionPane.ERROR_MESSAGE);
    18                 return;
    19             }
    20             // 打包
    21             int result = jfcSave.showSaveDialog(this);
    22             if(result == JFileChooser.APPROVE_OPTION) {
    23                 try {
    24                     // 清单文件
    25                     Manifest man = new Manifest();
    26                     // 版本和启动类路径必要
    27                     man.getMainAttributes().putValue(Name.MANIFEST_VERSION.toString(), "1.0");
    28                     man.getMainAttributes().putValue(Name.MAIN_CLASS.toString(), cobMainClass.getSelectedItem().toString());
    29                     // Class-Path一定不要,除非能保证将引用类(即import的类)都联合打包了
    30                     JarOutputStream jos = new JarOutputStream(new FileOutputStream(jfcSave.getSelectedFile()), man);
    31                     jos.setLevel(Deflater.BEST_COMPRESSION);
    32                     BufferedInputStream bis = null;
    33                     byte[] cache = new byte[1024];
    34                     StringBuffer config = new StringBuffer();
    35                     for(String name : filePaths.keySet()) {
    36                         bis = new BufferedInputStream(new FileInputStream(filePaths.get(name)), 1024);
    37                         config.append(name).append('=').append(bis.available()).append('
    ');
    38                         jos.putNextEntry(new JarEntry(name));
    39                         int count;
    40                         while((count = bis.read(cache, 0, 1024)) != -1)
    41                             jos.write(cache, 0, count);
    42                         jos.closeEntry();
    43                         bis.close();
    44                     }
    45                     jos.flush();
    46                     jos.close();
    47                     JOptionPane.showMessageDialog(this, "导出成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
    48                     System.exit(0);
    49                 } catch(Exception ex) {
    50                     JOptionPane.showMessageDialog(this, ex.getMessage(), "异常", JOptionPane.ERROR_MESSAGE);
    51                     System.exit(1);
    52                 }
    53             }
    54         }
    55         
    56     }
    btnConfirm_event_handler

      当然,这里还有一个小问题:选择文件(自己写的文件名就算不加后缀也能保存成功-_-)。

      先展示一下结果:

      

      在文件系统中选择:

      

      导出到桌面:

      

      

      运行一下:

      

      我最后再将完整的源码贴出一份:

      1 package org.coderecord.commons.ejarmaker;
      2 
      3 import java.awt.Toolkit;
      4 import java.awt.event.ActionEvent;
      5 import java.awt.event.ActionListener;
      6 import java.io.BufferedInputStream;
      7 import java.io.File;
      8 import java.io.FileInputStream;
      9 import java.io.FileOutputStream;
     10 import java.util.ArrayList;
     11 import java.util.HashSet;
     12 import java.util.Hashtable;
     13 import java.util.Iterator;
     14 import java.util.List;
     15 import java.util.Map;
     16 import java.util.Set;
     17 import java.util.jar.JarEntry;
     18 import java.util.jar.JarOutputStream;
     19 import java.util.jar.Manifest;
     20 import java.util.jar.Attributes.Name;
     21 import java.util.zip.Deflater;
     22 
     23 import javax.swing.JButton;
     24 import javax.swing.JComboBox;
     25 import javax.swing.JFileChooser;
     26 import javax.swing.JFrame;
     27 import javax.swing.JLabel;
     28 import javax.swing.JOptionPane;
     29 import javax.swing.JScrollPane;
     30 import javax.swing.JTextArea;
     31 import javax.swing.filechooser.FileFilter;
     32 
     33 public class FrmMain extends JFrame implements ActionListener {
     34 
     35     private static final long serialVersionUID = 2016913328739206536L;
     36     // 选择的文件(用户在文件选择器中选择的)
     37     private List<File> userSelectedFiles = new ArrayList<>();
     38     // 我们经过分析得到的最终会被打包的文件
     39     private List<File> finalFiles = new ArrayList<>();
     40     // 文件打包路径及物理文件
     41     private Map<String, File> filePaths = new Hashtable<>();
     42     
     43     public FrmMain() {
     44         setSize(480, 320);
     45         setResizable(false);
     46         setLocationRelativeTo(null);
     47         setTitle("通用可执行Jar包生成工具");
     48         setDefaultCloseOperation(EXIT_ON_CLOSE);
     49         setLayout(null);
     50         // 在运行时获取资源文件的方式,一定是使用Class.getResource方式
     51         // 在jar包中这种方式也行得通
     52         // ‘/’代表根路径
     53         setIconImage(Toolkit.getDefaultToolkit().getImage(FrmMain.class.getResource("/resources/icon.png")));
     54         initComponents();
     55     }
     56     
     57     // 初始化组件
     58     private void initComponents() {
     59         // 提示
     60         lblTip = new JLabel("选择需要打包的文件并设置启动类");
     61         lblTip.setLocation(20, 10);
     62         lblTip.setSize(350, 20);
     63         add(lblTip);
     64         
     65         // 浏览按钮
     66         btnBrowser = new JButton("浏 览");
     67         btnBrowser.setLocation(380, 10);
     68         btnBrowser.setSize(80, 24);
     69         btnBrowser.addActionListener(this);
     70         add(btnBrowser);
     71         
     72         // 展示已选择文件
     73         JScrollPane jspFiles = new JScrollPane();
     74         txtFiles = new JTextArea();
     75         txtFiles.setEditable(false);
     76         jspFiles.setSize(440, 160);
     77         jspFiles.setLocation(20, 40);
     78         txtFiles.setSize(440, 201600);
     79         txtFiles.setLocation(20, 40);
     80         txtFiles.setFocusable(false);
     81         jspFiles.setViewportView(txtFiles);
     82         add(jspFiles);
     83         
     84         // 选择启动类
     85         cobMainClass = new JComboBox<>();
     86         cobMainClass.setSize(440, 30);
     87         cobMainClass.setLocation(20, 210);
     88         add(cobMainClass);
     89         
     90         // 清除已选
     91         btnCls = new JButton("重 选");
     92         btnCls.setLocation(20, 250);
     93         btnCls.setSize(80, 24);
     94         btnCls.addActionListener(this);
     95         add(btnCls);
     96 
     97         // 确认按钮
     98         btnConfirm = new JButton("确认");
     99         btnConfirm.setSize(80, 24);
    100         btnConfirm.setLocation(380, 250);
    101         btnConfirm.addActionListener(this);
    102         add(btnConfirm);
    103         
    104         // 文件选择器
    105         jfcSelect = new JFileChooser();
    106         // 可以选择文件和文件夹
    107         jfcSelect.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
    108         // 可以多选
    109         jfcSelect.setMultiSelectionEnabled(true);
    110         
    111         // 文件保存
    112         jfcSave = new JFileChooser();
    113         // 设置只接受以“.jar”结尾的文件
    114         jfcSave.setAcceptAllFileFilterUsed(false);
    115         jfcSave.setFileFilter(new FileFilter() {
    116             
    117             @Override
    118             public String getDescription() {
    119                 return "可执行Jar";
    120             }
    121             
    122             @Override
    123             public boolean accept(File f) {
    124                 return f.getName().endsWith(".jar");
    125             }
    126         });
    127     }
    128 
    129     @Override
    130     public void actionPerformed(ActionEvent e) {
    131         if(e.getSource() == btnBrowser) {
    132             // 浏览
    133             int result = jfcSelect.showOpenDialog(this);
    134 
    135             // 选择了文件
    136             if(result == JFileChooser.APPROVE_OPTION) {
    137                 for(File file : jfcSelect.getSelectedFiles())
    138                     userSelectedFiles.add(file);
    139                 
    140                 // 整理选择的文件,去除重复项
    141                 removeDuplicateItems(userSelectedFiles);
    142                 
    143                 // 重新计算选中文件
    144                 finalFiles.clear();
    145                 for(File file : userSelectedFiles)
    146                     addFileToList(file, finalFiles);
    147                 
    148                 // 计算文件展示打包路径及展示路径
    149                 // 计算可启动类路径
    150                 // 展示到文本框中
    151                 cobMainClass.removeAllItems();
    152                 txtFiles.setText("");
    153                 File file,direc;
    154                 String filePath,direcPath;
    155                 Iterator<File> itd,itf;
    156                 for(itd = userSelectedFiles.iterator(); itd.hasNext();) {
    157                     direc = itd.next();
    158                     direcPath = direc.getAbsolutePath();
    159                     for(itf = finalFiles.iterator(); itf.hasNext();) {
    160                         file = itf.next();
    161                         filePath = file.getAbsolutePath();
    162                         if(filePath.equalsIgnoreCase(direcPath)) {
    163                             txtFiles.append(file.getName() + "
    ");
    164                             filePaths.put(file.getName(), file);
    165                             if(file.getName().endsWith(".class"))
    166                                 cobMainClass.addItem(file.getName().endsWith(".class")?file.getName().substring(0, file.getName().lastIndexOf('.')):file.getName());
    167                             itf.remove();
    168                         } else if(filePath.startsWith(direcPath)) {
    169                             String nameTmp = filePath.substring(direcPath.lastIndexOf(File.separator) + 1).replace(File.separatorChar, '/'); 
    170                             filePaths.put(nameTmp, file);
    171                             txtFiles.append(nameTmp + "
    ");
    172                             if(nameTmp.endsWith(".class") && nameTmp.indexOf('$') == -1)
    173                                 cobMainClass.addItem(nameTmp.substring(0, nameTmp.lastIndexOf('.')).replace('/', '.'));
    174                             itf.remove();
    175                         }
    176                     }
    177                 }
    178             }
    179         } else if(e.getSource() == btnCls) {
    180             if(userSelectedFiles.size() == 0) return;
    181             else if(JOptionPane.showConfirmDialog(this, "确定重选吗?将清除所有已选项!") == JOptionPane.OK_OPTION) {
    182                 userSelectedFiles.clear();
    183                 finalFiles.clear();
    184                 filePaths.clear();
    185                 cobMainClass.removeAllItems();
    186             }
    187         } else if(e.getSource() == btnConfirm) {
    188             if(filePaths.size() == 0) {
    189                 JOptionPane.showMessageDialog(this, "未选择文件", "错误", JOptionPane.ERROR_MESSAGE);
    190                 return;
    191             } else if(cobMainClass.getSelectedItem() == null) {
    192                 JOptionPane.showMessageDialog(this, "未选择启动类", "错误", JOptionPane.ERROR_MESSAGE);
    193                 return;
    194             }
    195             // 打包
    196             int result = jfcSave.showSaveDialog(this);
    197             if(result == JFileChooser.APPROVE_OPTION) {
    198                 try {
    199                     // 清单文件
    200                     Manifest man = new Manifest();
    201                     // 版本和启动类路径必要
    202                     man.getMainAttributes().putValue(Name.MANIFEST_VERSION.toString(), "1.0");
    203                     man.getMainAttributes().putValue(Name.MAIN_CLASS.toString(), cobMainClass.getSelectedItem().toString());
    204                     // Class-Path一定不要,除非能保证将引用类(即import的类)都联合打包了
    205                     JarOutputStream jos = new JarOutputStream(new FileOutputStream(jfcSave.getSelectedFile()), man);
    206                     jos.setLevel(Deflater.BEST_COMPRESSION);
    207                     BufferedInputStream bis = null;
    208                     byte[] cache = new byte[1024];
    209                     StringBuffer config = new StringBuffer();
    210                     for(String name : filePaths.keySet()) {
    211                         bis = new BufferedInputStream(new FileInputStream(filePaths.get(name)), 1024);
    212                         config.append(name).append('=').append(bis.available()).append('
    ');
    213                         jos.putNextEntry(new JarEntry(name));
    214                         int count;
    215                         while((count = bis.read(cache, 0, 1024)) != -1)
    216                             jos.write(cache, 0, count);
    217                         jos.closeEntry();
    218                         bis.close();
    219                     }
    220                     jos.flush();
    221                     jos.close();
    222                     JOptionPane.showMessageDialog(this, "导出成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
    223                     System.exit(0);
    224                 } catch(Exception ex) {
    225                     JOptionPane.showMessageDialog(this, ex.getMessage(), "异常", JOptionPane.ERROR_MESSAGE);
    226                     System.exit(1);
    227                 }
    228             }
    229         }
    230         
    231     }
    232     
    233     // 添加文件(非文件夹)到集合
    234     private void addFileToList(File file, List<File> fileArr) {
    235         if(file.isDirectory())
    236             for(File child : file.listFiles())
    237                 addFileToList(child, fileArr);
    238         else
    239             fileArr.add(file);
    240     }
    241     
    242     // 去除重复项
    243     private void removeDuplicateItems(List<File> fileArr) {
    244         // 去重复项
    245         Set<String> directories = new HashSet<>();
    246         Set<String> files = new HashSet<>();
    247         for(File file : fileArr)
    248             if(file.isDirectory())
    249                 directories.add(file.getAbsolutePath());
    250             else
    251                 files.add(file.getAbsolutePath());
    252         //去包含项(先去文件夹再去文件应该更好)
    253         String fpath,dpath;
    254         for(Iterator<String> itf = files.iterator(); itf.hasNext();) {
    255             fpath = itf.next();
    256             for(Iterator<String> itd = directories.iterator(); itd.hasNext();) {
    257                 dpath = itd.next();
    258                 if(fpath.startsWith(dpath))
    259                     itf.remove();
    260             }
    261         }
    262         String dpath1,dpath2;
    263         Set<String> directories1 = new HashSet<>(directories);
    264         for(Iterator<String> itd1 = directories.iterator(); itd1.hasNext();) {
    265             dpath1 = itd1.next();
    266             for(Iterator<String> itd2 = directories1.iterator(); itd2.hasNext();) {
    267                 dpath2 = itd2.next();
    268                 if(dpath1.equals(dpath2))
    269                     continue;
    270                 else if(dpath2.startsWith(dpath1))
    271                     itd2.remove();
    272                 else if(dpath1.startsWith(dpath2))
    273                     itd1.remove();
    274             }
    275         }
    276         directories.addAll(directories1);
    277         
    278         fileArr.clear();
    279         for(String file : files)
    280             fileArr.add(new File(file));
    281         for(String directory : directories)
    282             fileArr.add(new File(directory));
    283     }
    284     
    285     private JLabel lblTip;
    286     private JButton btnBrowser;
    287     private JFileChooser jfcSelect;
    288     private JTextArea txtFiles;
    289     private JComboBox<String> cobMainClass;
    290     private JButton btnCls;
    291     private JButton btnConfirm;
    292     private JFileChooser jfcSave;
    293 }
    FrmMain

      这里有我导出的文件(这个是eclipse导出的,它在manifest中加入了classPath没有错误,我有时候加入后有问题)。

     欢迎您移步我们的交流群,无聊的时候大家一起打发时间:Programmer Union

     或者通过QQ与我联系:点击这里给我发消息

     (最后编辑时间2014-03-02 16:12:50)

  • 相关阅读:
    SSAS : 如何在http访问SSAS中指定语言标识
    网络开发:在Socket中发送大文件
    CSS应用及其优先级问题
    SSAS : 使用.NET为SSAS编写自定义程序集
    SSAS : 如何编写自定义挖掘算法
    什么是高清视频
    SSAS : 使用.NET为SSAS编写自定义程序集(二)
    循证架构寻找最适合自己的架构
    有道难题,我的OO解法
    假如我是海洋
  • 原文地址:https://www.cnblogs.com/Johness/p/3576920.html
Copyright © 2011-2022 走看看