技术开发 频道

将基于 Swing 的开发工具插入 Eclipse 中

  由于大多数编辑器最初被设计为独立的 Java 应用程序设计,所以它们不注意 Workbench 的存在。它们可能不能处理 Platform 的一些环境属性,这就限制了编辑器与 Platform 集成的亲密度。为了给用户提供一个更平滑更一致的开发体验,开发者和插件供应商应该认真考虑增强他们现有的 Swing 工具从而使其变为 Workbench 知晓的。

  例如,Ed 被编码为直接处理基于文件系统的 Java 文件。因此,Platform 的 Java Project 和 Project Reference 与 Ed 无关。在这一部分中,我们将把 JButton添加到 Ed 以启动一个 SWT 对话框,该对话框显示了已编辑的 ThirdParty.java 被引用的项目。从用户角度看,他单击一个 Swing 小窗口,触发了一个显示特定于 Workbench 的信息的 SWT 窗口,这表示 Swing 编辑器、SWT 以及 Workbench 彼此正在紧密交互。

  增强编辑器

  假设您具有对 Ed 源代码的访问权,您可以添加额外的 Swing 小窗口以获得额外的 Workbench 知晓性功能。将 JButton添加到编辑器的主内容窗格,然后它会启动一个 SWT 对话框。将 JButton的文本设置为“Referenced Project”。

  Referenced Project 按钮的事件处理机制的工作方式将与 Save 按钮的工作方式类似。插件实用程序类将侦听来自这个按钮的事件。实用程序类一接收到 Referenced Project 按钮触发的一个事件对象,它就会执行必要的操作来检索项目引用信息并在 SWT 中显示该信息。

  检索项目引用信息

  在 SWT 对话框可以被显示之前,插件需要弄明白包含已编辑的 ThirdParty.java 的项目引用了 Workbench 中的哪些项目。这是插件类的工作,而且它可以使用如清单 8 所示的一种方法,其中传入该方法的字符串变量是项目的名称:

  清单 8. 检索项目引用信息

1 private String[] getReferencedProjectArray(String arg) {
2    String[] projectNameArray = null;
3   
4    try {
5       IProject[] referencedProjects =
6          ResourcesPlugin.getWorkspace().getRoot().getProject(
7             arg).getReferencedProjects();
8       
9       int referencedProjectsLength = referencedProjects.length;
10       
11       if (referencedProjectsLength == 0) {
12          projectNameArray = new String[1];
13          projectNameArray[0] = "none";
14       }
15       else {
16          projectNameArray = new String[referencedProjectsLength];
17          for (int i=0; i < referencedProjectsLength; i++) {
18             projectNameArray[i] = referencedProjects[i].getName();
19          }
20       }
21       return projectNameArray;
22    } catch (Exception e) {
23       e.printStackTrace();
24       return null;
25    }
26 }
27

  SWT 对话框

  Project Referenced SWT 对话到底应该会是什么样子要由插件 GUI 设计师决定。在这个示例中,一个带有 List 对象的简单的 SWT Shell(要显示引用的项目)就足够了:

  清单 9. 带有 List 对象的 SWT Shell

1 public class SWTProjectReferenceFrame implements Runnable {
2    private Shell shell;
3    private Display display;
4    Thread myThread;
5   
6    public void run() {
7       open();
8    }
9   
10    public void open() {
11       display = new Display();
12       shell = new Shell(display);
13       shell.setLayout(new org.eclipse.swt.layout.GridLayout());
14       shell.setText("Projects Referenced - SWT Frame");
15       shell.setSize(400, 400);
16       createListGroup();
17       shell.open();
18       
19       while (!shell.isDisposed()) {
20          if (!display.readAndDispatch()) {
21             EditorintegrationPlugin.getDefault().getEd().repaint();
22             display.sleep();
23          }
24       }
25       myThread = null; // disposing the thread when the SWT window is disposed.
26    }
27   
28    // Other methods appear here ...
29 }
30

  方法 createListGroup() 准备了 List 对象并设置其内容以包含 projectNameArray。

  清单 10. 准备 List 对象

1 private void createListGroup() {
2    Group listGroup = new Group(shell, SWT.NULL);
3    listGroup.setLayout(new GridLayout());
4    listGroup.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL |
5                                         GridData.HORIZONTAL_ALIGN_FILL |
6                                         GridData.VERTICAL_ALIGN_FILL));
7    listGroup.setText("listGroup");
8   
9    List list = new List(listGroup, SWT.V_SCROLL);
10    list.setItems(projectNameArray);
11 }
12

  根据启动 SWT 对话框的方式,您可能需要在一个单独的线程(如清单 10 中的 myThread 对象所指出的那样)中执行 SWT 窗口以避免在 Swing 编辑器中的重绘制(repaint)问题。

  图 5中显示了 Swing按钮启动一个 SWT 框架。

  图 5. 从 Swing 按钮启动一个 SWT 框架

  结束语

  这里描述的这些技术提供了一个临时的解决方案,它可以帮助您快速地将基于 Swing 的工具集成到 Eclipse Platform 中。但是,只要有可能,您就应该在现有的 Swing 小窗口上使用紧密集成的 SWT/JFace 组件。例如,编辑器应该用 Eclipse Platform 的 Preference Page 框架作为配置插件的中心入口点,而不是用各个引用对话框框架来处理多个用户引用。

  尽管本文中的这些概念相对简单且易于实现,但是请不要将 Swing 小窗口作为永久设备留在插件中。要控制和利用 Eclipse 项目中的所有服务,您就应该逐渐减少插件中陈旧的 Swing 代码的数量以便支持 Eclipse 项目提供的各种框架。

0
相关文章