如何根据WizardPage动态调整JFace WizardDialog大小?
JFace WizardDialog 动态适配WizardPage内容尺寸方案
WizardDialog 仅在首次打开、切换页面时会自动计算一次外壳尺寸,单页内动态增减控件时不会主动触发重算,就会出现内容截断问题,按以下步骤实现即可:
核心实现逻辑
- 自定义可主动触发尺寸刷新的WizardDialog子类,把尺寸计算逻辑封装在公共方法里,避免页面层重复写代码:
public class AutoResizeWizardDialog extends WizardDialog { public AutoResizeWizardDialog(Shell parentShell, IWizard wizard) { super(parentShell, wizard); } /** * 根据当前页面内容重新计算对话框尺寸,适配动态变更的控件 */ public void refreshSize() { Shell dialogShell = getShell(); if (dialogShell == null || dialogShell.isDisposed()) { return; } // 递归布局当前页面所有控件,确保拿到最新的控件尺寸 IWizardPage currentPage = getCurrentPage(); if (currentPage != null && currentPage.getControl() != null) { currentPage.getControl().layout(true, true); } // 计算对话框最优尺寸,自动包含标题栏、底部按钮栏的固定高度 Point preferredSize = dialogShell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); // 增加少量边距避免内容贴边 preferredSize.x += 20; preferredSize.y += 10; // 限制尺寸不超过当前显示器工作区,避免对话框超出屏幕 Rectangle screenArea = dialogShell.getMonitor().getClientArea(); preferredSize.x = Math.min(preferredSize.x, screenArea.width); preferredSize.y = Math.min(preferredSize.y, screenArea.height); // 应用新尺寸 dialogShell.setSize(preferredSize); } }
- 替换原有创建WizardDialog的代码,使用自定义的自动调整大小的对话框:
final PageAccess page = new PageAccess(...); WizCreate wiz = new WizCreate() { @Override public boolean performFinish() { page.performFinish(); return true; } }; wiz.addPage(page); Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); // 替换为自定义的支持动态尺寸的对话框 AutoResizeWizardDialog dialog = new AutoResizeWizardDialog(shell, wiz); dialog.open();
- 在PageAccess的SelectionListener实现里,完成控件新增/移除、布局参数设置后,主动调用尺寸刷新方法:
@Override public void widgetSelected(SelectionEvent e) { // 此处写原有控件增删、内容更新逻辑 // ... 所有控件变更完成后,调用刷新方法 ((AutoResizeWizardDialog)getWizard().getContainer()).refreshSize(); }
注意避坑
- 动态内容的容器Composite不要写死
widthHint/heightHint布局参数,保持为SWT.DEFAULT即可,否则会导致尺寸计算错误。 - 如果页面包含Table、Tree、StyledText这类自带滚动条的控件,要给这类控件设置合理的固定
heightHint/widthHint,避免控件把对话框撑到超出屏幕。 - 不要在控件创建、添加的过程中调用
refreshSize(),必须等所有控件挂载到控件树、布局参数设置完成后再调用,否则计算出的尺寸会偏小。 - 如果首次打开页面就存在动态加载的内容,可以重写PageAccess的
setVisible(boolean visible)方法,在第一次显示时调用一次refreshSize(),保证初始尺寸正确。
内容的提问来源于stack exchange,提问作者Marco Roda
相关产品推荐
相关产品推荐

