使用原生Java代码生成可执行Jar包

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

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

  效果如下:

  使用原生Java代码生成可执行Jar包

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

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

  代码如下:

  Main

使用原生Java代码生成可执行Jar包
 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(只是界面代码,业务代码最后贴出)

使用原生Java代码生成可执行Jar包
  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

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

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

使用原生Java代码生成可执行Jar包
  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() + "\n");

 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 + "\n");

 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包:

使用原生Java代码生成可执行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('\n');

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

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

  先展示一下结果:

  使用原生Java代码生成可执行Jar包

  在文件系统中选择:

  使用原生Java代码生成可执行Jar包

  导出到桌面:

  使用原生Java代码生成可执行Jar包

  使用原生Java代码生成可执行Jar包

  运行一下:

  使用原生Java代码生成可执行Jar包

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

使用原生Java代码生成可执行Jar包
  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() + "\n");

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 + "\n");

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('\n');

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)

你可能感兴趣的:(java)