首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Swing 實作啟動畫面 (Splash Screen) 完整教學:從基礎到自動關閉與執行緒安全

     編輯:Java 相關知識

前言

啟動畫面 (Splash Screen) 是現代應用程式的標準配備,既能展示品牌形象,又能在漫長的初始化過程中提供視覺回饋。本文循序漸進示範如何使用 Swing JWindow 建立專業級啟動畫面,涵蓋置中顯示、滑鼠點擊關閉、定時自動關閉、以及 Swing 執行緒安全處理。

階段一:基礎版 - 置中顯示圖片

class SplashWindow1 extends JWindow {
    public SplashWindow1(String filename, Frame f) {
        super(f);
        JLabel l = new JLabel(new ImageIcon(filename));
        getContentPane().add(l, BorderLayout.CENTER);
        pack();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension labelSize = l.getPreferredSize();
        setLocation(screenSize.width/2 - labelSize.width/2,
                    screenSize.height/2 - labelSize.height/2);
        setVisible(true);
    }
}

關鍵點:JWindow 無標題列/邊框/按鈕,適合啟動畫面;pack() 自動依圖片大小調整視窗;螢幕置中計算公式。

階段二:加入滑鼠點擊關閉

class SplashWindow2 extends JWindow {
    public SplashWindow2(String filename, Frame f) {
        super(f);
        JLabel l = new JLabel(new ImageIcon(filename));
        getContentPane().add(l, BorderLayout.CENTER);
        pack();
        // ... 置中程式碼同前 ...
        
        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                setVisible(false);
                dispose();
            }
        });
        setVisible(true);
    }
}

匿名 MouseAdapter 處理點擊事件,呼叫 dispose() 釋放原生資源。

階段三:定時自動關閉 - 執行緒安全關鍵

class SplashWindow3 extends JWindow {
    public SplashWindow3(String filename, Frame f, int waitTime) {
        super(f);
        JLabel l = new JLabel(new ImageIcon(filename));
        getContentPane().add(l, BorderLayout.CENTER);
        pack();
        // ... 置中程式碼同前 ...
        
        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                setVisible(false);
                dispose();
            }
        });
        
        final int pause = waitTime;
        final Runnable closerRunner = new Runnable() {
            public void run() {
                setVisible(false);
                dispose();
            }
        };
        
        Runnable waitRunner = new Runnable() {
            public void run() {
                try {
                    Thread.sleep(pause);
                    SwingUtilities.invokeAndWait(closerRunner);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        
        setVisible(true);
        Thread splashThread = new Thread(waitRunner, "SplashThread");
        splashThread.start();
    }
}

核心概念深度解析

為什麼需要 SwingUtilities.invokeAndWait()?

Swing 非執行緒安全,所有 UI 操作必須在 事件派發執行緒 (Event Dispatch Thread, EDT) 執行。waitRunner 運行於獨立執行緒,睡眠結束後不能直接呼叫 setVisible(false),必須透過 SwingUtilities.invokeAndWait() 將 closerRunner 排入 EDT 隊列執行。

兩個 Runnable 的分工

Runnable執行緒職責
waitRunner背景執行緒 (SplashThread)計時等待,不操作 UI
closerRunnerEDT (透過 invokeAndWait)實際關閉視窗、釋放資源

invokeAndWait vs invokeLater

  • invokeAndWait:同步阻塞,等待 EDT 執行完畢才返回,適合「必須確保關閉完成」的場景
  • invokeLater:非同步,立即返回,適合一般 UI 更新

進階應用場景

  • 不可關閉的啟動畫面:移除滑鼠監聽器與 closerRunner,由主程式初始化完成後主動呼叫 setVisible(false); dispose()
  • 僅限手動關閉:保留滑鼠監聽器,移除定時器執行緒
  • 顯示載入進度:在 JWindow 加入 JProgressBar,主程式透過 SwingUtilities.invokeLater() 更新進度
  • Java 6+ 內建支援:java.awt.SplashScreen 類別提供原生級啟動畫面支援 (需配合 -splash:image.png JVM 參數)

完整使用範例

public class MyApp {
    public static void main(String[] args) {
        // 1. 顯示啟動畫面 (4 秒自動關閉,可點擊關閉)
        SplashWindow3 splash = new SplashWindow3("splash.png", null, 4000);
        
        // 2. 執行耗時初始化 (資料庫連線、配置載入、快取預熱...)
        try { Thread.sleep(3000); } catch (Exception e) {}
        
        // 3. 啟動主視窗
        SwingUtilities.invokeLater(() -> {
            JFrame mainFrame = new JFrame("主程式");
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mainFrame.setSize(800, 600);
            mainFrame.setVisible(true);
        });
    }
}

最佳實踐總結

  1. 使用 JWindow 而非 JFrame 避免多餘窗口元素
  2. 圖片建議使用 PNG 格式 (支援透明背景),尺寸控制在 400x300 以內
  3. 所有 UI 操作必須在 EDT 執行,善用 SwingUtilities.invokeAndWait/InvokeLater
  4. dispose() 必須呼叫以釋放原生視窗資源
  5. Java 6 以上專案優先考慮原生 SplashScreen API
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved