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

SWT 顯示圖片完整範例:從載入到事件迴路

     編輯:Java 程式設計入門

Eclipse Standard Widget Toolkit (SWT) 使用作業系統原生圖形庫,啟動快、記憶體佔用低,適合桌面應用開發。本文示範載入本地圖片、設定 Shell 大小、繪製圖片與標準事件迴路。

Maven 依賴 (Windows x86_64)

<dependency>
    <groupId>org.eclipse.platform</groupId>
    <artifactId>org.eclipse.swt.win32.win32.x86_64</artifactId>
    <version>3.120.0</version> <!-- 對應 Eclipse 2022-09 -->
</dependency>

其他平台請換用對應 artifactId (cocoa.macosx.x86_64, gtk.linux.x86_64 等)。

完整可運行程式碼

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class SwtImageDemo {

    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.DOUBLE_BUFFERED);
        shell.setText("SWT 圖片檢視器");

        // 1. 載入圖片 (支援 BMP, GIF, JPEG, PNG, TIFF)
        String imagePath = "C:/images/sample.jpg"; // 請替換為實際路徑
        Image image;
        try {
            image = new Image(display, imagePath);
        } catch (Exception e) {
            System.err.println("圖片載入失敗: " + e.getMessage());
            display.dispose();
            return;
        }

        // 2. 依圖片尺寸調整 Shell (加上邊框補償)
        Rectangle bounds = image.getBounds();
        shell.setSize(bounds.width + 16, bounds.height + 39); // Windows 標題列約 39px

        // 3. 設定 Shell 圖示 (可選)
        shell.setImage(image);

        // 4. 繪製圖片 - 必須在 PaintListener 中進行,否則視窗重繪會丟失
        shell.addPaintListener(e -> {
            GC gc = e.gc;
            gc.drawImage(image, 0, 0); // 左上角對齊
        });

        shell.open();

        // 5. 標準事件迴路
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }

        // 6. 釋放資源 (Image 必須手動 dispose)
        image.dispose();
        display.dispose();
    }
}

關鍵點深度解析

步驟說明注意事項
Display 建立SWT 應用程式進入點,管理平台資源每執行緒僅能有一個 Display;主執行緒自動建立
Image 建立綁定特定 Display,不可跨 Display 使用必須手動 dispose(),否則洩漏 GDI/記憶體
PaintListener正確繪製時機,支援視窗最小化/遮擋後恢復不要在 open() 前直接用 GC 繪製,會被擦除
事件迴路readAndDispatch() 處理佇列事件;sleep() 釋放 CPU若無 sleep() 會佔滿單核 CPU
資源釋放Image、Display、Color、Font、GC 皆需 dispose建議使用 try-with-resources 或統一清理

進階:圖片縮放與自適應

shell.addPaintListener(e -> {
    GC gc = e.gc;
    Rectangle clientArea = shell.getClientArea();
    Rectangle imgBounds = image.getBounds();

    double scale = Math.min(
        (double) clientArea.width / imgBounds.width,
        (double) clientArea.height / imgBounds.height
    );

    int drawWidth = (int) (imgBounds.width * scale);
    int drawHeight = (int) (imgBounds.height * scale);
    int x = (clientArea.width - drawWidth) / 2;
    int y = (clientArea.height - drawHeight) / 2;

    gc.drawImage(image, 0, 0, imgBounds.width, imgBounds.height, x, y, drawWidth, drawHeight);
});

// 視窗大小改變時觸發重繪
shell.addListener(SWT.Resize, e -> shell.redraw());

常見問題排查

  • UnsatisfiedLinkError:未引入正確平台的 SWT JAR,或 32/64 位元不匹配。
  • 圖片不顯示/空白:路徑錯誤、格式不支援、未加 PaintListener、Image 已 dispose。
  • Mac 選單列問題:Mac 需設定 System.setProperty("apple.laf.useScreenMenuBar", "true") 並使用 SWT.APPLICATION_MENU。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved