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

Eclipse RCP 開發實戰(五):SWT 2D 繪圖詳解

     編輯:Java 相關知識

前言

SWT 圖形系統核心在於 org.eclipse.swt.graphics 套件。本文透過「畫圖板」範例,詳細講解 GC(Graphics Context)、Image、Canvas 協作機制,以及解決視窗最小化/遮擋導致繪圖消失的 PaintListener 機制。

核心類別關係圖

  • Device:繪圖裝置抽象,子類 Display(螢幕)、Printer(印表機)。
  • Drawable:可繪製介面,實作類包括 Control(所有 UI 控制項)、Image(離屏圖像)。
  • GC (Graphics Context):繪圖上下文,建構子需 Drawable,封裝所有繪圖方法(drawLine、fillRectangle、drawImage 等)。
  • Image:建構子需 Device,支援從檔案/資料流載入。

基礎繪圖範例:菜單觸發繪製

// CanvasView.java
public class CanvasView extends ViewPart {
    public Canvas canvas;
    @Override public void createPartControl(Composite parent) {
        canvas = new Canvas(parent, SWT.NONE);
    }
    @Override public void setFocus() { canvas.setFocus(); }
}

// DrawOvalAction.java (菜單/工具列 Action)
public void run(IAction action) {
    IViewPart view = findView("畫圖板");
    if (view instanceof CanvasView) {
        GC gc = new GC(((CanvasView)view).canvas);
        gc.drawOval(80, 50, 100, 100);  // x, y, width, height
        gc.dispose();  // 必須釋放系統資源
    }
}

// DrawGradientAction.java
GC gc = new GC(canvas);
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.fillGradientRectangle(80, 200, 100, 100, false);  // false=垂直漸層
gc.dispose();

// DrawImageAction.java
GC gc = new GC(canvas);
Image img = new Image(display, "E:/img.gif");
gc.drawImage(img, 280, 200);
gc.dispose();
img.dispose();  // Image 亦需手動釋放

關鍵問題:重繪機制與 PaintListener

直接在 GC 上繪圖屬於「即時模式」,視窗最小化、被遮擋、切換分頁後,SWT 會重繪控制項,導致圖形消失。

解決方案:保留繪圖指令,在 Paint 事件中重播

public class CanvasView extends ViewPart {
    public Canvas canvas;
    private List<DrawCommand> commands = new ArrayList<>();  // 自定義命令物件

    @Override public void createPartControl(Composite parent) {
        canvas = new Canvas(parent, SWT.NONE);
        canvas.addPaintListener(e -> {
            GC gc = e.gc;  // 系統提供的 GC,無需 dispose
            for (DrawCommand cmd : commands) {
                cmd.execute(gc);
            }
        });
    }

    // 供 Action 呼叫
    public void addCommand(DrawCommand cmd) {
        commands.add(cmd);
        canvas.redraw();  // 觸發重繪
    }
}

// 命令模式封裝
interface DrawCommand { void execute(GC gc); }

class DrawOvalCmd implements DrawCommand {
    private final int x, y, w, h;
    public DrawOvalCmd(int x, int y, int w, int h) { this.x=x; this.y=y; this.w=w; this.h=h; }
    public void execute(GC gc) { gc.drawOval(x, y, w, h); }
}

// Action 中改為:
view.addCommand(new DrawOvalCmd(80, 50, 100, 100));

GC 進階功能速覽

功能方法範例
前景/背景色gc.setForeground(color); gc.setBackground(color);
線條樣式gc.setLineStyle(SWT.LINE_DASH); gc.setLineWidth(2);
文字繪製gc.drawText("Hello", 10, 10, true); // true=抗鋸齒
裁剪區域gc.setClipping(x, y, w, h); // 限制繪圖範圍
變換矩陣Transform t = new Transform(display); t.rotate(45); gc.setTransform(t);
Alpha 透明度gc.setAlpha(128); // 0-255

資源管理鐵律

  • 自建 GC(new GC(drawable))必須 dispose()。
  • PaintEvent.gc 由系統管理,不可 dispose。
  • Image、Font、Color、Region 等裝置資源皆需手動 dispose()。
  • 使用 Display.getSystemColor() 取得的系統色彩 不可 dispose。

總結

SWT 2D 繪圖核心在於 GC 與 Drawable 的分離設計。掌握 命令模式保留繪圖指令 + PaintListener 重播 模式,即可實現持久化、可縮放、可列印的向量繪圖應用。善用 fillGradientRectangle、drawImage、Transform 等進階 API,能輕鬆構建豐富視覺效果。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved