長期以來,AWT 與 Swing 是 Java GUI 開發的雙支柱,但功能侷限、外觀平庸、更新緩慢。Java SE 6 (2006 發布) 為這兩大圖形庫注入強心劑,引入啟動畫面無碼整合、系統托盤 API、標準對話框、GIF 讀寫支援等關鍵特性,大幅縮短與原生桌面應用的體驗差距。本文深度體驗這四大核心功能。
早期版本需手動建立無邊框視窗、載入圖片、計時關閉、再顯示主視窗,程式碼繁瑣且難以維護。
# 無需修改任何 Java 程式碼!
java -splash:splash.png -jar MyApp.jar
核心優勢:
SplashScreen.getSplashScreen().getGraphics() 可繪製進度條、狀態文字public class SplashDemo {
public static void main(String[] args) {
// 模擬初始化過程
SplashScreen splash = SplashScreen.getSplashScreen();
if (splash != null) {
Graphics2D g = splash.createGraphics();
for (int i = 0; i <= 100; i += 10) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, splash.getSize().width, splash.getSize().height);
g.setColor(Color.BLUE);
g.drawString("載入中... " + i + "%", 20, 100);
g.fillRect(20, 120, i * 3, 20);
splash.update();
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
}
splash.close();
}
// 啟動主應用...
new MainFrame().setVisible(true);
}
}
Java SE 5 以前無標準 API,唯有 JNI 呼叫平台原生庫,犧牲跨平台性且開發極其困難。
java.awt.SystemTrayif (SystemTray.isSupported()) {
SystemTray tray = SystemTray.getSystemTray();
Image icon = Toolkit.getDefaultToolkit().getImage("app-icon.png");
// 建立彈出選單
PopupMenu popup = new PopupMenu();
MenuItem openItem = new MenuItem("開啟主視窗");
MenuItem exitItem = new MenuItem("退出");
popup.add(openItem);
popup.addSeparator();
popup.add(exitItem);
// 建立托盤圖示
TrayIcon trayIcon = new TrayIcon(icon, "My Application", popup);
trayIcon.setImageAutoSize(true); // 自動縮放適應各平台托盤尺寸
// 事件處理
openItem.addActionListener(e -> showMainFrame());
exitItem.addActionListener(e -> System.exit(0));
trayIcon.addActionListener(e -> showMainFrame()); // 雙擊圖示
try {
tray.add(trayIcon);
// 顯示氣球提示 (Windows/Linux 支援)
trayIcon.displayMessage("啟動完成", "應用程式正在背景運行", TrayIcon.MessageType.INFO);
} catch (AWTException e) {
System.err.println("無法加入系統托盤: " + e.getMessage());
}
} else {
System.out.println("當前平台不支援系統托盤");
}
| 平台 | 托盤支援 | 氣球提示 | 圖示建議尺寸 |
|---|---|---|---|
| Windows | 完整支援 | 支援 | 16x16, 32x32 |
| Linux (GNOME/KDE) | 支援 (需系統托盤小程式運行) | 部分支援 | 22x22, 32x32 |
| macOS | 菜單列右側 (非傳統托盤) | 不支援 | 16x16, 32x32 (模板圖片最佳) |
Java SE 6 擴充 JOptionPane 並新增 Desktop 類,提供開箱即用的標準對話框:
| 對話框類型 | 用途 | 關鍵 API |
|---|---|---|
| 訊息對話框 | 提示、警告、錯誤、資訊 | JOptionPane.showMessageDialog() |
| 確認對話框 | 是/否/取消 選擇 | JOptionPane.showConfirmDialog() |
| 輸入對話框 | 單行文字輸入 (類 Delphi InputBox) | JOptionPane.showInputDialog() |
| 選項對話框 | 自訂按鈕選項 | JOptionPane.showOptionDialog() |
| 檔案選擇器 | 開啟/儲存檔案、目錄選擇 | JFileChooser (增強版) |
| 顏色選擇器 | RGB/HSV 顏色選取 | JColorChooser |
String name = JOptionPane.showInputDialog(
frame,
"請輸入您的姓名:",
"歡迎",
JOptionPane.QUESTION_MESSAGE
);
if (name != null && !name.trim().isEmpty()) {
JOptionPane.showMessageDialog(frame, "你好, " + name + "!");
}
GIF 使用 LZW 壓縮演算法,受 Unisys 專利限制,Java 早期版本唯讀不寫入。2003-2004 年專利在各國到期,Java SE 6 終於在 ImageIO 框架中完整支援 GIF 讀寫。
// 讀取 GIF
BufferedImage img = ImageIO.read(new File("animation.gif"));
// 寫入 GIF (單幀)
ImageIO.write(bufferedImage, "gif", new File("output.gif"));
// 多幀動畫寫入需使用 ImageWriter 進階 API
ImageWriter writer = ImageIO.getImageWritersByFormatName("gif").next();
ImageWriteParam param = writer.getDefaultWriteParam();
try (ImageOutputStream ios = ImageIO.createImageOutputStream(new File("anim.gif"))) {
writer.setOutput(ios);
writer.prepareWriteSequence(null);
for (BufferedImage frame : frames) {
writer.writeToSequence(new IIOImage(frame, null, null), param);
}
writer.endWriteSequence();
}
TYPE_BYTE_INDEXED 並指定調色盤 (256 色)javax.imageio.metadata.IIOMetadata 設定 (單位:百分之一秒)public class ModernApp {
public static void main(String[] args) {
// 1. 設定系統外觀 (可選)
try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }
catch (Exception ignored) {}
// 2. 啟動畫面已透過 -splash 參數顯示
// 3. 背景初始化資源
SwingUtilities.invokeLater(() -> {
// 模擬初始化
initResources();
// 4. 建立主視窗
JFrame frame = new MainFrame();
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); // 隱藏而非退出
// 5. 整合系統托盤
setupSystemTray(frame);
// 6. 顯示主視窗
frame.setVisible(true);
});
}
private static void setupSystemTray(JFrame frame) {
if (!SystemTray.isSupported()) return;
SystemTray tray = SystemTray.getSystemTray();
Image icon = new ImageIcon("icon.png").getImage();
TrayIcon trayIcon = new TrayIcon(icon, "ModernApp", createPopupMenu(frame));
trayIcon.setImageAutoSize(true);
trayIcon.addActionListener(e -> {
frame.setVisible(true);
frame.setExtendedState(JFrame.NORMAL);
});
try { tray.add(trayIcon); } catch (AWTException ignored) {}
}
private static PopupMenu createPopupMenu(JFrame frame) {
PopupMenu menu = new PopupMenu();
MenuItem show = new MenuItem("顯示主視窗");
MenuItem exit = new MenuItem("退出");
show.addActionListener(e -> frame.setVisible(true));
exit.addActionListener(e -> System.exit(0));
menu.add(show);
menu.addSeparator();
menu.add(exit);
return menu;
}
}
Java SE 6 為 AWT/Swing 帶來四大里程碑功能:
-splash 參數 + 動態更新 API,零侵入專業體驗SystemTray/TrayIcon 統一跨平台 API,背景常駐必備JOptionPane、JFileChooser、JColorChooser,減少重複造輪子ImageIO 完整支援,含動畫編碼這些特性在現代 Java 版本中依然核心有效,是構建專業桌面應用的基石工具箱。