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

SWT/RCP 非矩形窗體實戰:Region、圖片遮罩與媒體播放器界面構建

     編輯:Java 相關知識

前言:打破 Eclipse 「灰藍方正」刻板印象

SWT 結合原生界面庫,效能與外觀兼顧,但預設僅支援矩形窗體。通過 org.eclipse.swt.graphics.Region 定義任意多邊形、結合圖片透明通道提取輪廓,可實現圓形按鈕、異形窗口、媒體播放器等酷炫界面——且 RCP 應用同樣適用。

Region 幾何建模基礎

坐標數組定義多邊形


// 逆時針頂點:x1,y1, x2,y2, ...
int[] rect = {0,0,  0,320,  520,320,  520,0};  // 矩形
int[] rect2 = {50,320,  50,370,  470,370,  470,320}; // 另一矩形
Region region = new Region();
region.add(rect);
region.add(rect2);  // 疊加形成 L 形

多邊形疊加示意圖

算法生成圓形/弧形


int[] circle(int r, int offsetX, int offsetY) {
    int[] ring = new int[8 * r + 4];
    for (int i = 0; i < 2 * r + 1; i++) {
        int x = i - r;
        int y = (int) Math.sqrt(r * r - x * x);
        ring[2 * i] = offsetX + x;
        ring[2 * i + 1] = offsetY + y;
        ring[8 * r - 2 * i - 2] = offsetX + x;
        ring[8 * r - 2 * i - 1] = offsetY - y;
    }
    return ring;
}

圓形坐標生成原理圖

減法運算:挖洞


region.subtract(circle(20, 400, 345));  // 在右下角挖圓洞

SWT 窗體應用 Region


Display display = new Display();
Shell shell = new Shell(display, SWT.NO_TRIM); // 無標題欄邊框
Region region = new Region();
region.add(getBackRect1());
region.add(getBackRect2());
region.subtract(circle(20, 400, 345));
shell.setRegion(region);
Rectangle bounds = region.getBounds();
shell.setSize(bounds.width, bounds.height);
shell.open();
// 事件循環...
region.dispose(); display.dispose();

多邊形窗口運行效果

關鍵點:

  • SWT.NO_TRIM 移除系統裝飾,Region 完全接管外形
  • setRegion 後必須 setSize 為 Region bounds
  • Region 屬於裝置資源,必須 dispose()

Control 非矩形:圖片 + Region 疊加

Eclipse 3.4+ 才原生支援 Control.setRegion,早期版本採用「透明圖片 + Region 裁剪」變通:


Button btn = new Button(shell, SWT.PUSH);
Image img = new Image(display, "play.png");
Region btnRegion = new Region();
btnRegion.add(circle(35, 40, 40)); // 圓形點擊區
btn.setRegion(btnRegion);
btn.setSize(img.getBounds().width + 10, img.getBounds().height + 10);
btn.setImage(img);

圓形按鈕效果

圓形控件原理示意圖

原理:Region 定義響應區域,圖片提供視覺邊界,超出 Region 點擊無響應。

圖片透明通道自動提取 Region

手工寫坐標極其繁瑣,利用 ImageData.getTransparencyMask() 掃描非零像素:


Region getRegionFromImage(Display display, String path) {
    ImageLoader loader = new ImageLoader();
    ImageData[] data = loader.load(path);
    ImageData img = data[0];
    ImageData mask = img.getTransparencyMask();
    Region region = new Region(display);
    Rectangle pixel = new Rectangle(0,0,1,1);
    for (int y=0; y

同時設置背景圖:


Image bgImage = new Image(display, data[0]);
shell.setBackgroundImage(bgImage);

圖片提取 Region 窗口效果

完整代碼見 清單 6,單張 PNG/GIF 同時定義形狀與皮膚。

RCP 應用:WorkbenchWindowAdvisor 定制窗體

啟動流程鉤子

RCP 啟動時序圖

  • Application → WorkbenchAdvisor → WorkbenchWindowAdvisor
  • 重寫三關鍵方法:
    • preWindowOpen():設置 SWT.NO_TRIM | SWT.NO_BACKGROUND
    • createWindowContents():創建 Page、按鈕等控件,設置 Region
    • postWindowCreate():獲取 Shell,應用 Region、背景圖、拖拽移動監聽

媒體播放器界面完整實現

媒體播放器界面

核心代碼片段:


// postWindowCreate - 窗體形狀與背景
Shell shell = configurer.getWindow().getShell();
backRegion = getRegionFromImage(shell.getDisplay(), backImage);
shell.setRegion(backRegion);
shell.setSize(imgWidth, imgHeight);
// 拖拽移動 + 重繪背景
shell.addListener(SWT.MouseDown, e -> { startX=e.x; startY=e.y; });
shell.addListener(SWT.MouseMove, e -> {
    if ((e.stateMask & SWT.BUTTON1) != 0) {
        Point p = shell.toDisplay(e.x, e.y);
        shell.setLocation(p.x - startX, p.y - startY);
    }
});
shell.addListener(SWT.Paint, e -> e.gc.drawImage(backImage, 0, 0));

// createWindowContents - Page 與按鈕
Composite page = configurer.createPageComposite(shell);
page.setRegion(getRegionFromImage(display, pageImage));
page.setBounds(45, 21, pageW, pageH);

Button playBtn = new Button(shell, SWT.PUSH);
playBtn.setRegion(circleRegion(35));
playBtn.setImage(playImg);
playBtn.addSelectionListener(e -> openMediaEditor());

Button exitBtn = new Button(shell, SWT.PUSH);
exitBtn.setRegion(getRegionFromImage(display, exitImg));
exitBtn.setImage(exitImg);
exitBtn.addSelectionListener(e -> PlatformUI.getWorkbench().close());

注意:

  • Page (Composite) 同樣支援 setRegion
  • 控件層級需管理 Z-order,避免遮擋
  • 拖拽移動需自行實現(無標題欄)

總結與最佳實踐

技術點建議
複雜形狀優先用圖片透明通道提取,避免手算坐標
圖片格式PNG (無損透明) > GIF (單色透明) > JPEG (不支援透明)
效能Region 越複雜,重繪/命中測試越慢,適度簡化
RCP 整合在 WorkbenchWindowAdvisor 統一管理,避免分散在各 View/Editor
無裝飾窗口必須自行實現:移動、最小化/最大化/關閉、重繪

SWT/RCP 的 Region 機制將「像素級界面控制權」交還開發者,配合圖片皮膚,構建差異化桌面應用不再是夢。

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