如何设置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ű
相关产品推荐
相关产品推荐

