如果标准对话框对于您的插件来说太简单,可以使用 Dialog 类来构建您自己的对话框。先前,我们已经了解了自述文件工具如何在操作集中添加“打开自述文件浏览器”操作。此操作集显示在工作台工具栏和窗口 -> 自述文件编辑器菜单中。
现在,我们准备在自述文件工具的 WindowActionDelegate 中了解此操作的实现。
public void run(IAction action) { SectionsDialog dialog = new SectionsDialog(window.getShell(), ReadmeModelFactory.getInstance().getSections(selection)); dialog.open(); }
操作集的窗口操作代表使用资源导航器视图(.readme 文件)中的当前选择来获取自述文件中各小节的列表。此列表和工作台窗口的 shell 传送至 SectionsDialog。
当用户选择该操作时,SectionsDialog 就会打开。
SectionsDialog 是通过对 org.eclipse.jface.dialogs 包中的 Dialog 类划分子类,从而在自述文件工具插件中实现的。
Dialog 类提供了对构建对话框 shell 窗口、创建常见对话框按钮以及启动对话框的基本支持。子类负责处理对话框本身的内容:
SectionsDialog 创建 SWT 列表,以显示各小节的列表。它使用 JFace 查看器来填充列表。(我们将了解查看器中的 JFace 查看器。)注意,我们的对话框不需要为对话框创建任何按钮,原因是这是由超类来完成的。
protected Control createDialogArea(Composite parent) { Composite composite = (Composite)super.createDialogArea(parent); List list = new List(composite, SWT.BORDER); ... ListViewer viewer = new ListViewer(list); ... return composite; }
protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText(MessageUtil.getString("Readme Sections")); ... }
对话框既可以比较简单,也可以比较复杂,这取决于实际需要。实现对话框时,大多数对话框代码都与创建 SWT 控件(表示它的内容区域)和处理对话框打开时的任何必需的事件有关。一旦用户按了按钮,对话框就可以查询组成该对话框的各种控件(或查看器)的状态,以确定应该执行哪些操作。
在某些情况下,您可能想在对话框中显示关于某些内容的信息,但必须使用比启动正规对话框更“轻量级”的方式来显示该信息。例如,可使用一个对话框来提供可以方便地废弃的瞬态信息,而不干扰用户的工作。在这种情况下,可以使用 PopupDialog 类来实现对话框。PopupDialog 的外观在某些方面与正规的 Dialog 不同。它的底部没有任何按钮,它没有标准的窗口标题栏,并且,它的边框、间距和字体都较小并更为紧凑。
虽然 PopupDialog 的外观与正规对话框很不相同,但在插件的子类中,用于定义对话框内容的代码却几乎相同。仍然实现 createDialogArea 方法来创建对话框的 SWT 控件。应用程序代码的主要差别是,与正规的 Dialog 类相比,用于创建对话框的构造函数增加了许多参数。例如,通过仅仅更改对话框的超类并在构造函数配置对话框,可以将 SectionsDialog 转换为 PopupDialog:
public class SectionsDialog extends PopupDialog { protected IAdaptable input; /** * Creates a new SectionsDialog. */ public SectionsDialog(Shell parentShell, IAdaptable input) { super(parentShell, SWT.DEFAULT, false, // do not take focus when opened false, // do not persist the bounds false, // do not show a resize menu false, // do not show a menu item for persisting bounds null, // no title null); // no info text this.input = input; } ...