You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设置SWT Dialog的显示位置?弹窗居中问题排查与解决

SWT Dialog总是居中?教你自定义显示位置

哈哈,这个坑我之前踩过!你现在的问题核心是时机不对——你在dialog.open()之后才去处理位置,但SWT的Dialog默认就是居中显示,而且open()方法是阻塞的,执行到这一行时Dialog已经弹出来了,后面的代码要等Dialog关闭才会跑,这时候再设置位置当然没用啦😆

为什么Dialog默认居中?

SWT的Dialog类内部自带了布局逻辑:如果有父Shell,就显示在父Shell的中央;没有父Shell的话,就默认显示在屏幕中央。而且open()方法已经把Dialog的创建、布局、显示全做完了,事后再改位置根本不生效。

解决方法:提前在Dialog内部设置位置

最稳妥的方式是在自定义的MyDialog里重写createContents()方法,在Dialog创建内容的阶段就指定好位置。比如这样改你的MyDialog:

public class MyDialog extends Dialog {
    public MyDialog(Shell parentShell, String title) {
        super(parentShell);
        setText(title);
    }

    @Override
    protected Control createContents(Composite parent) {
        // 先调用父类方法创建默认内容
        Control control = super.createContents(parent);
        
        // 获取当前光标位置(就是你之前打印的pt)
        Point cursorLocation = Display.getCurrent().getCursorLocation();
        // 获取Dialog窗口的大小
        Point dialogSize = parent.getShell().getSize();
        
        // 这里可以自定义位置逻辑:比如让Dialog中心和光标对齐
        int targetX = cursorLocation.x - dialogSize.x / 2;
        int targetY = cursorLocation.y - dialogSize.y / 2;
        
        // 也可以直接让Dialog左上角跟光标位置重合:targetX = cursorLocation.x; targetY = cursorLocation.y;
        
        // 最后设置Dialog的位置
        parent.getShell().setLocation(targetX, targetY);
        
        return control;
    }
}

然后你的调用代码就可以保持原样:

@Override 
public void widgetSelected(SelectionEvent e) { 
    Dialog dialog = new MyDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "MyDialog"); 
    dialog.open(); 
    // 这里的代码会在Dialog关闭后才执行,所以之前的打印其实是关闭后才输出的
    Point pt = ImageDisplayHelper.getDisplay().getCursorLocation(); 
    System.out.println("location pt: "+pt); 
}

额外提醒:避免Dialog跑出屏幕

如果直接用光标位置计算,可能会出现Dialog一半在屏幕外面的情况,可以加个边界判断:

Display display = Display.getCurrent();
Rectangle screenBounds = display.getBounds();

// 确保x不小于0,且Dialog右边不超出屏幕
targetX = Math.max(0, Math.min(targetX, screenBounds.width - dialogSize.x));
// 确保y不小于0,且Dialog下边不超出屏幕
targetY = Math.max(0, Math.min(targetY, screenBounds.height - dialogSize.y));

内容的提问来源于stack exchange,提问作者Sanyifejű

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:04:05