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); } }
右鍵項目進行導包成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
