使用EXE4J和Inno Setup 編譯器將java程序打包成windows桌面應用安裝程序


java項目結構如下:

 

 

Demo是模仿程序快照,主要設計兩個按鈕:保存快照和恢復快照;

保存快照將對象(窗口)序列化保存下來,后面無論做了什么操作,只要點擊恢復快照,

就會讀取之前保存的序列化的對象。

 

package demo;

import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

/**
 * 提供保存快照和恢復快照方法的類
 * @date    2019年3月11日下午3:58:55
 * @version 1.0
 */
class Snapshot{
    //快照文件
    String snapshotFile = "E:/Snapshot.dat";
    
    //保存快照
    public void saveSnapshot(MyFrame myFrame) throws IOException {
        FileOutputStream fout = null;
        ObjectOutputStream out = null;//對象輸出流
        
        try {
            fout = new FileOutputStream(snapshotFile);
            out = new ObjectOutputStream(fout);//構造對象輸出流
            out.writeObject(myFrame);//序列化
        } catch (FileNotFoundException e) {
            System.out.println("建立快照文件失敗");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("寫出發生了I/O異常");
            e.printStackTrace();
        }finally {
            if (out != null) {
                out.close();//只關閉處理流
            }
        }
    }
    
    public MyFrame loadSnapshot() throws IOException{//讀取快照
        MyFrame myFrame = null;//存放恢復的窗口
        FileInputStream fin = null;
        ObjectInputStream in = null;//對象輸入流
        
        try {
            fin =  new FileInputStream(snapshotFile);
            in = new ObjectInputStream(fin);//構造對象輸入流
            myFrame = (MyFrame)in.readObject();//反序列化
        } catch (FileNotFoundException e) {
            System.out.println("讀取快照文件失敗");
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            System.out.println("找不到相應的類");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("讀取發生I/O異常");
            e.printStackTrace();
        }finally {
            if (in != null) {
                in.close();
            }
        }
        
        return myFrame;
    }
    
}

//實現Serializable接口的類的對象才能被序列化
class MyFrame extends JFrame implements ActionListener, Serializable{
    /** serialVersionUID*/
    private static final long serialVersionUID = -8045215058120011473L;
    /*更改java默認標題欄圖標*/
    
    JButton save = new JButton("保存快照");
    JButton Load = new JButton("恢復快照");
    
    JPanel panel = new JPanel();
    
    JTextArea textArea = new JTextArea("初始文字"); 
    JScrollPane scrollPane = new JScrollPane(textArea);
    //不序列化此字段
    transient Snapshot snapshot = new Snapshot();
    
    //snapshot字段的setter方法
    public void setSnapshot(Snapshot snapshot) {
        this.snapshot = snapshot;
    }
    
    public MyFrame() {
        initUI();
        save.addActionListener(this);
        Load.addActionListener(this);
    }

    private void initUI() {
        
        // C:\\Users\\Administrator\\Desktop\\sna\\img\\ds.ico
        // /img/ds.ico
        
        String img_path = "/img/tanke.jpg";
            
        //Image img = ImageIO.read(this.getClass().getResource(img_path));
        Image img = (Toolkit.getDefaultToolkit().getImage(this.getClass().getResource(img_path)));
        setIconImage(img);
        
        setLayout(new BorderLayout());
        textArea.setLineWrap(true);
        add(scrollPane, BorderLayout.CENTER);
        panel.add(save);
        panel.add(Load);
        add(panel, BorderLayout.SOUTH);
        setTitle("程序快照機");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(200,140);
        
        
    }

    @Override
    public void actionPerformed(ActionEvent e) {//當控件被激活時,jvm將傳遞ActionEvent對象通知
        
        
        try{
            if(e.getSource() == save){
                snapshot.saveSnapshot(this);
                System.out.println(e);
            }else {
                //否則單擊的是恢復快照的按鈕
                MyFrame f = snapshot.loadSnapshot();
                //此行不可少,因為為序列化MyFrame類的snapshot字段
                f.setSnapshot(new Snapshot());
                f.setVisible(true);//顯示恢復原來的窗口
                this.dispose();//關閉原來的窗口
            }
        }catch (Exception e1) {
            System.out.println("保存快照時發生I/O錯誤");
        }
        
        
    }
    
}


public class SnapshotDemo {
    
    public static void main(String[] args) {
        MyFrame demo = new MyFrame();
        demo.setVisible(true);
        
    }
    
}
View Code

 

右鍵項目進行導包成jar文件,資源文件不導。如圖所示

  

 

  下一步

  

  下一步

  

  我們在test項目底下創建MAINFEST.MF文件,文件內容如下:

  

Manifest-Version: 1.0
Main-Class: snapshot.SnapshotDemo
Class-Path: 
Created-By: your name

  其中class-Path我們可不指定,因為在后面的exe4j中會設置到

  選擇好后界面如下:

 點擊finish后就可以在輸出目錄看到jar文件,這時我們還需將資源文件(如:img)拷到該目錄,由於exe4j支持jdk_win32,我們只要拷走jdk中的jre文件。

視圖如下:

 

 其中exe4j依賴低版本的jdk1.6。在這里我將exe4j、jdk1.6_32、jdk1.7_32、innoSetup文件放在:

百度網盤:

鏈接:https://pan.baidu.com/s/1Tizt5qOh8JLDHo3RzVdwrA
提取碼:w1cz

下面開始使用exe4j將jar和資源文件打包成exe程序:

 

下一步

 

 下一步

下一步

設置好后界面如下:

 

 下一步

下面我們來指定jre的位置,由於我把jre拷到跟jar同層目錄,如下所示:

 

 下面的一直默認下一步,程序運行效果圖:

此時我們可以將jre和jar刪除,因為已經打包在demo.exe中了

 

 


 

 

 

下面我們開始用InnoSteup來編譯windows桌面安裝程序:

下一步

下一步

下一步

下一步

下一步

下一步

下一步

然后下一步下面都點是,最后它會要讓你選擇一個位置保存編譯文件,必須選。

 

大功告成

 

看效果圖:

安裝后目錄:

 

 

參考:

用exe4j+Inno_setup打包java桌面應用

https://blog.csdn.net/yege2006/article/details/51312989

 

一鍵搞定Java桌面應用安裝部署 —— exe4j + Inno Setup 帶着JRE, 8M起飛

https://blog.csdn.net/ouyangxin95/article/details/53009173

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM