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

1 packageorg.coderecord.commons.ejarmaker;2

3 importjava.awt.Toolkit;4 importjava.awt.event.ActionEvent;5 importjava.awt.event.ActionListener;6 importjava.io.BufferedInputStream;7 importjava.io.File;8 importjava.io.FileInputStream;9 importjava.io.FileOutputStream;10 importjava.util.ArrayList;11 importjava.util.HashSet;12 importjava.util.Hashtable;13 importjava.util.Iterator;14 importjava.util.List;15 importjava.util.Map;16 importjava.util.Set;17 importjava.util.jar.JarEntry;18 importjava.util.jar.JarOutputStream;19 importjava.util.jar.Manifest;20 importjava.util.jar.Attributes.Name;21 importjava.util.zip.Deflater;22

23 importjavax.swing.JButton;24 importjavax.swing.JComboBox;25 importjavax.swing.JFileChooser;26 importjavax.swing.JFrame;27 importjavax.swing.JLabel;28 importjavax.swing.JOptionPane;29 importjavax.swing.JScrollPane;30 importjavax.swing.JTextArea;31 importjavax.swing.filechooser.FileFilter;32

33 public class FrmMain extends JFrame implementsActionListener {34

35 private static final long serialVersionUID = 2016913328739206536L;36 //选择的文件(用户在文件选择器中选择的)

37 private List userSelectedFiles = new ArrayList<>();38 //我们经过分析得到的最终会被打包的文件

39 private List finalFiles = new ArrayList<>();40 //文件打包路径及物理文件

41 private Map filePaths = new Hashtable<>();42

43 publicFrmMain() {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 voidinitComponents() {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 = newJScrollPane();74 txtFiles = newJTextArea();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 = newJFileChooser();106 //可以选择文件和文件夹

107 jfcSelect.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);108 //可以多选

109 jfcSelect.setMultiSelectionEnabled(true);110

111 //文件保存

112 jfcSave = newJFileChooser();113 //设置只接受以“.jar”结尾的文件

114 jfcSave.setAcceptAllFileFilterUsed(false);115 jfcSave.setFileFilter(newFileFilter() {116

117 @Override118 publicString getDescription() {119 return "可执行Jar";120 }121

122 @Override123 public booleanaccept(File f) {124 return f.getName().endsWith(".jar");125 }126 });127 }128

129 @Override130 public voidactionPerformed(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 Iteratoritd,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 = newManifest();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(newFileOutputStream(jfcSave.getSelectedFile()), man);206 jos.setLevel(Deflater.BEST_COMPRESSION);207 BufferedInputStream bis = null;208 byte[] cache = new byte[1024];209 StringBuffer config = newStringBuffer();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(newJarEntry(name));214 intcount;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, ListfileArr) {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(ListfileArr) {244 //去重复项

245 Set directories = new HashSet<>();246 Set 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 itf =files.iterator(); itf.hasNext();) {255 fpath =itf.next();256 for(Iterator 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 directories1 = new HashSet<>(directories);264 for(Iterator itd1 =directories.iterator(); itd1.hasNext();) {265 dpath1 =itd1.next();266 for(Iterator 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(newFile(file));281 for(String directory : directories)282 fileArr.add(newFile(directory));283 }284

285 privateJLabel lblTip;286 privateJButton btnBrowser;287 privateJFileChooser jfcSelect;288 privateJTextArea txtFiles;289 private JComboBoxcobMainClass;290 privateJButton btnCls;291 privateJButton btnConfirm;292 privateJFileChooser jfcSave;293 }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值