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

SWT/JFace 圓環視窗實作:非矩形 Shell、Region 裁剪與拖曳移動

     編輯:Java 程式設計入門

完整程式碼


package swt_jface.demo1;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

public class RingShell {
    // 產生圓周頂點座標陣列
    private int[] createCircle(int radius, int centerX, int centerY) {
        int[] points = new int[360 * 2];
        for (int i = 0; i < 360; i++) {
            double rad = Math.toRadians(i);
            points[i * 2] = centerX + (int) (radius * Math.cos(rad));
            points[i * 2 + 1] = centerY + (int) (radius * Math.sin(rad));
        }
        return points;
    }

    private Point originalPosition = null;

    public RingShell() {
        Display display = new Display();
        // 無邊框、置頂
        Shell shell = new Shell(display, SWT.NO_TRIM | SWT.ON_TOP);
        shell.setBackground(display.getSystemColor(SWT.COLOR_DARK_MAGENTA));

        // 建立 Region:外圓減去內圓 = 圓環
        Region region = new Region();
        region.add(createCircle(100, 100, 100));      // 外半徑 100
        region.subtract(createCircle(50, 100, 100));  // 內半徑 50
        shell.setRegion(region);                      // 套用非矩形視窗

        // 滑鼠拖曳移動視窗
        shell.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseDown(MouseEvent e) {
                originalPosition = new Point(e.x, e.y);
            }
            @Override
            public void mouseUp(MouseEvent e) {
                originalPosition = null;
            }
            @Override
            public void mouseDoubleClick(MouseEvent e) {
                display.dispose(); // 雙擊關閉
            }
        });

        shell.addMouseMoveListener(new MouseMoveListener() {
            @Override
            public void mouseMove(MouseEvent e) {
                if (originalPosition == null) return;
                Point pt = display.map(shell, null, e.x, e.y); // 轉換為螢幕座標
                shell.setLocation(pt.x - originalPosition.x, pt.y - originalPosition.y);
            }
        });

        // 依 Region 邊界設定 Shell 大小
        Rectangle bounds = region.getBounds();
        shell.setSize(bounds.width, bounds.height);
        shell.open();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }
        display.dispose();
        region.dispose(); // 釋放 Region 資源
    }

    public static void main(String[] args) {
        new RingShell();
    }
}

核心技術解析

技術點實現方式
非矩形視窗Shell(SWT.NO_TRIM | SWT.ON_TOP) 移除標題列/邊框、置頂顯示
形狀裁剪Region.add()/subtract() 布爾運算組合幾何形狀,shell.setRegion(region) 套用
圓周點陣生成參數方程 x = cx + r·cos(θ), y = cy + r·sin(θ),360 點近似圓
拖曳移動mouseDown 記錄相對座標 → mouseMove display.map() 轉螢幕座標 → shell.setLocation()
資源釋放Region.dispose()、Display.dispose() 必須成對調用

進階擴充想法

  • 漸層/圖片填充:shell.setBackgroundImage() 或在 PaintListener 中繪製漸層。
  • 點擊穿透:Windows 需 JNA 呼叫 SetWindowLong(WS_EX_TRANSPARENT);跨平台較複雜。
  • 動畫效果:計時器漸變 shell.setAlpha()(需 SWT.ALPHA 支援)或縮放 Region。
  • 系統托盤整合:Tray + TrayItem 實現最小化到托盤、右鍵選單。

適用場景

  • 桌面小工具(時鐘、CPU 監控、便利貼)
  • 螢幕取色器、放大鏡等浮動工具
  • 遊戲外掛/輔助覆蓋層(需注意反作弊)
  • 非標準形狀啟動畫面
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved