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

蹲街弑〆低调 提交于 2020-03-29 04:38:58

  最近想做一个功能,就是把我们编译后的字节码及其资源文件打包成一个可执行的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() + "\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包:

 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

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

  先展示一下结果:

  

  在文件系统中选择:

  

  导出到桌面:

  

  

  运行一下:

  

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

  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没有错误,我有时候加入后有问题)。

 

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

 或者通过QQ与我联系:

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!