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

Java Swing 實現啟動畫面:JWindow 動態倒數等待

     編輯:Java 程式設計入門

一、啟動畫面設計要點

  • 無標題列、無邊框 → 繼承 JWindow(而非 JFrame)。
  • 圖片與視窗同步顯示 → 使用 MediaTracker 等待圖片載入完成。
  • 動態更新狀態文字 → 覆寫 paint(Graphics) 繪製圖片與文字。
  • 主視窗啟動前關閉啟動畫面 → 另一執行緒跑倒數,時間到 dispose()。

二、核心類別:SplashWindow

public class SplashWindow extends JWindow {
    private String statusText = "";
    private Image logoImg;

    public SplashWindow(JFrame owner) {
        super(owner);
        // 1. 載入圖片(從 classpath 讀取)
        logoImg = Toolkit.getDefaultToolkit().getImage(
            ClassLoader.getSystemResource("images/splash.jpg"));
        // 2. MediaTracker 同步等待圖片載入
        MediaTracker tracker = new MediaTracker(this);
        tracker.addImage(logoImg, 0);
        try { tracker.waitForAll(); } catch (InterruptedException ignored) {}

        // 3. 置中螢幕、依圖片尺寸設定視窗大小
        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation((screen.width - logoImg.getWidth(this)) / 2,
                    (screen.height - logoImg.getHeight(this)) / 2);
        setSize(logoImg.getWidth(this), logoImg.getHeight(this));
    }

    // 對外更新狀態文字
    public void setStatus(String text) {
        this.statusText = text;
        repaint(); // 觸發 paint()
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        if (logoImg != null) g.drawImage(logoImg, 0, 0, this);
        if (statusText != null && !statusText.isEmpty()) {
            g.setColor(Color.RED);
            g.drawString(statusText, 240, getHeight() - 250);
        }
    }
}

三、主視窗整合:MainFrame

public class MainFrame extends JFrame implements Runnable {
    private SplashWindow splash;

    private void init() throws Exception {
        // 1. 啟動 Splash 視窗執行緒
        Thread splashThread = new Thread(this);
        splashThread.start();
        splashThread.join(); // 等待 Splash 顯示完成

        // 2. 模擬初始化耗時工作(35 秒),期間更新 Splash 狀態
        long start = System.currentTimeMillis();
        while (System.currentTimeMillis() - start < 35000) {
            int remain = 35 - (int)((System.currentTimeMillis() - start) / 1000);
            if (splash != null) splash.setStatus("Waiting " + remain);
            Thread.sleep(100); // 降低 CPU 佔用
        }

        // 3. 關閉 Splash,顯示主視窗
        if (splash != null) {
            splash.dispose();
            splash = null;
        }
        setVisible(true);
    }

    @Override
    public void run() {
        splash = new SplashWindow(this);
        splash.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try { new MainFrame().init(); }
            catch (Exception e) { e.printStackTrace(); }
        });
    }
}

四、關鍵技術點解析

技術點作用
JWindow無裝飾視窗,適合啟動畫面、工具提示等輕量彈出層
MediaTracker同步追蹤圖片載入狀態,避免視窗顯示後圖片延遲出現
repaint() vs paint()repaint() 排程重繪,paint() 實際繪製邏輯;切勿直接呼叫 paint()
雙執行緒協作Splash 顯示執行緒 + 主初始化執行緒,透過 join() 同步
dispose()釋放原生視窗資源,必須在事件調度執行緒呼叫(本例已在 EDT)

五、現代化改良建議

  1. 改用 SwingWorker 執行後台初始化,publish()/process() 更新進度,避免手動 Thread.sleep。
  2. 圖片資源建議放入模組化 JAR,使用 Class.getResource() 載入。
  3. 高 DPI 螢幕下圖片需支援 @2x、@3x 多解析度版本。
  4. Java 9+ 可考慮 JFrame.setOpacity() 實現淡入淡出動畫。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved