使用EclipseRCP进行桌面程序开发(三):视图和透视图

Eclipse RCP开发中,和用户进行交互最多的界面,应该是视图了,而透视图就是将已有 的视图、菜单、工具栏、编辑器等等进行组合和布局。看完这一节,我们就可以建立如下图 这样的程序界面了。

首先我们来介绍一下视图,建立一个视图其实非常简单,只要从 org.eclipse.ui.part.ViewPart继承一个类,然后在plugin.xml中进行视图的配置。其中, 向视图中添加控件的操作,我们即可以手工编写,也可以使用Designer插件,我这里推荐大 家使用Designer插件,该插件对RCP提供功能非常强大的支持,如果使用Designer插件开发视 图,则plugin.xml文件也不需要我们手动修改了。

比如我们上图中的第一个视图,就是从ViewPart继承一个类,然后在上面加入了几个swt 的控件,做得非常得简单,而它的配置文件如下:

13   7

可以看到,实现这个视图的class为cn.blogjava.youxia.views.FirstView,那么我们看 看FirstView.java吧:

1package cn.blogjava.youxia.views;23import org.eclipse.jface.action.IMenuManager;4import org.eclipse.jface.action.IToolBarManager;5import org.eclipse.jface.viewers.TableViewer;6import org.eclipse.swt.SWT;7import org.eclipse.swt.widgets.Composite;8import org.eclipse.swt.widgets.Label;9import org.eclipse.swt.widgets.Table;10import org.eclipse.swt.widgets.Text;11import org.eclipse.ui.part.ViewPart;1213public class FirstView extends ViewPart {1415  private Table table;16  private Text text_1;17  private Text text;18  public static final String ID = "cn.blogjava.youxia.views.FirstView"; // $NON-NLS-1$1920  /** *//**21   * Create contents of the view part22   * @param parent23   */24  @Override25  public void createPartControl(Composite parent) {26    Composite container = new Composite(parent, SWT.NONE);2728    final Label label = new Label(container, SWT.NONE);29    label.setText("姓名:");30    label.setBounds(56, 41, 36, 12);3132    text = new Text(container, SWT.BORDER);33    text.setBounds(98, 38, 80, 15);3435    final Label label_1 = new Label(container, SWT.NONE);36    label_1.setText("性别:");37    label_1.setBounds(212, 41, 30, 12);3839    text_1 = new Text(container, SWT.BORDER);40    text_1.setBounds(252, 38, 80, 15);4142    final TableViewer tableViewer = new TableViewer(container, SWT.BORDER);43    //tableViewer.setInput(new Object());44    table = tableViewer.getTable();45    table.setBounds(56, 75, 374, 143);46    table.setItemCount(10);47    table.setLinesVisible(true);48    //49    createActions();50    initializeToolBar();51    initializeMenu();52      }5354  /** *//**55   * Create the actions56   */57  private void createActions() {58    // Create the actions59  }6061  /** *//**62   * Initialize the toolbar63   */64  private void initializeToolBar() {65    IToolBarManager toolbarManager = getViewSite().getActionBars()66        .getToolBarManager();67  }6869  /** *//**70   * Initialize the menu71   */72  private void initializeMenu() {73    IMenuManager menuManager = getViewSite().getActionBars()74        .getMenuManager();75  }7677  @Override78  public void setFocus() {79    // Set the focus80  }8182  }

其中,添加控件的代码由Disgner插件自动生成。这个时候,如果我们运行程序的话,我 们的视图还不会被显示出来。为了让我们的视图可以显示,我们还需要修改 Perspective.java文件,代码如下:

1package cn.blogjava.youxia.rcp_start;23import org.eclipse.ui.IPageLayout;4import org.eclipse.ui.IPerspectiveFacTory;56public class Perspective implements IPerspectiveFacTory {78  public void createInitialLayout(IPageLayout layout) {9    String ediTorArea = layout.getEdiTorArea();10    layout.addView("cn.blogjava.youxia.views.FirstView", IPageLayout.RIGHT, 0.2f, ediTorArea);11  }12}

运行程序,得到如下效果:

我们可以发现,上面这个视图的标签不是我们通常看到的波浪形,我们可以通过配置文件 的方式来更改产品的样式。

首先,在plugin.xml中对org.eclipse.core.runtime.products扩展点的属性进行更改, 如下:

4   7     10   11

可见,我们为我们的产品添加了一个prefereneCustomization属性,该属性的值为 plugin_customization.ini文件,在该文件中,我们可以配置我们的样式。在这里,它的内 容如下:

1org.eclipse.ui/SHOW_TRADITIONAL_STYLE_TABS=false

2org.eclipse.ui/DOCK_PERSPECTIVE_BAR=topRight

事实上,在这个文件中可以定义的参数有上百个,大家可以查看Eclipse的文档。

这个时候,效果应该是这样的了:

好了,我们现在对以上的代码做一个总结。我不是写教科书,在Blog中也没有写得那么详 细的条件。我们这里主要关注在哪个地方对代码进行扩展,可以达到我们想要的效果。比如 ,我们要创建视图,就是需要扩展org.eclipse.ui.part.ViewPart类,然后向其中添加控件 ,再然后配置plugin.xml文件,最后修改透视图的代码,以便它能够显示出来。

在ViewPart类中,我们添加控件的操作主要是在public void createPartControl (Composite parent)这个方法中进行,而方法最后会调用以下三个方法:

createActions();

initializeToolBar();

initializeMenu();

从这三个方法的方法名我们不难看出,它们的功能是创建视图特有的菜单栏和工具栏的, 结合上一小节的内容,我们应该很快就可以探索到怎么给视图添加漂亮的工具栏了,这里我 不再罗嗦。

再来看Perspective.java,不难发现,所有的透视图类都需要实现IPerspectiveFacTory 接口,而该接口的createInitialLayout方法,就是描述工作台窗口中编辑器和视图的布局。 默认情况下,透视图中只包含一个编辑器区域,就是我们第一节中看到的那个效果。在 createInitialLayou中,我们可以通过以下几个方法向透视图中添加视图、编辑器和菜单:

addView  —— 添加视图

addActionSet —— 添加菜单和工具栏

createFolder —— 创建一个IForderLayou,可以让多个视图重叠在同一个位置

写到这里,肯定有人会问,如果我要创建一个象Eclipse中的资源视图这样的视图,该怎 么做呢?这我们就要感谢org.eclipse.jface.viewers包了,Viewer,这里翻译为查看器,它 和视图是不一样的。JFace查看器是Jface对SWT部件的封装,它简化了我们对小部件的操作。 在使用查看器的时候,它的数据使用单独的模型对象来保存,使用查看器的setInput方法可 以为查看器设置模型,此外,在使用查看器的时候,需要为它提供ContentProvider(内容提 供器)和LabelProvider(标签提供器)。

JFace查看器主要分为以下几类:

1. ListViewer: 对应于SWT的列表控件,目的是将列表中的元素映射至SWT列表控件

2. TreeViewer: 对应于SWT的树控件,提供树的展开和折叠等基本操作

3. TableViewer: 对应于SWT的表控件,映射表中的元素

4. TextViewer: 对应于SWT的StyledText控件,创建编辑器的时候,使用这个查看器是 最合适不过了。

好了,介绍性的文字就写到这里,我想大家一定已经知道了探索的方向。下面,我们看一 个简单的示例,就是这篇文章开头给出的效果图。它是我模仿医院管理系统做的一个简单例 子,左边的视图就是使用了一个ListView查看器。这里给出它的关键代码:

public void createPartControl(Composite parent) {234    viewer = new ListViewer(parent, SWT.BORDER);5    viewer.setContentProvider(new PersonContentProvider());6    viewer.setLabelProvider(new PersonLabelProvider());7    viewer.setInput(new PersonModel());89    createActions();10    initializeToolBar();11    initializeMenu();12  }

可以看到,这里需要设置内容提供器和标签提供器和模型。下面,我们先创建一个病人类 Person.java:

1package cn.blogjava.youxia.views;23public class Person {45  private String name;6  private String sex;7  public String getName() {8    return name;9  }10  public void setName(String name) {11    this.name = name;12  }13  public String getSex() {14    return sex;15  }16  public void setSex(String sex) {17    this.sex = sex;18  }1920}

下面,创建模型类PersonModel.java,在构造函数中我们向List中填入了几个初始化数据 :

1package cn.blogjava.youxia.views;2import java.util.ArrayList;34public class PersonModel {56  private ArrayList list = new ArrayList();78  public interface Listener{9    public void add(Person p);10    public void remove(Person p);11  }1213  private Listener listener;1415  public PersonModel(){16    //向list里面填入几个初始化数据17    Person p1 = new Person();18    p1.setName("病人1");19    p1.setSex("男");20    list.add(p1);2122    Person p2 = new Person();23    p2.setName("病人2");24    p2.setSex("女");25    list.add(p2);26    27  }2829  public void setListener(Listener listener){30    this.listener = listener;31  }3233  public void add(Person p){34    list.add(p);35    if(listener != null){36      listener.add(p);37    }38  }3940  public void remove(Person p){41    list.remove(p);42    if(listener != null){43      listener.remove(p);44    }45  }46  47  public ArrayList elements(){48    return list;49  }50}

在这里,我们还定义了一个Listener接口,为什么要有这么一个接口呢?就是为了让我们 模型中的数据被改变时,查看器能够相应更改。下面,我们实现内容提供器,该内容提供器 实现了PersonModel中定义的Listener接口,如下PersonContentProvider.java:

1package cn.blogjava.youxia.views;23import org.eclipse.jface.viewers.IStructuredContentProvider;4import org.eclipse.jface.viewers.Viewer;5import org.eclipse.jface.viewers.ListViewer;67import cn.blogjava.youxia.views.PersonModel.Listener;89public class PersonContentProvider implements IStructuredContentProvider,10    Listener {1112  PersonModel input;13  ListViewer viewer;1415  public Object[] getElements(Object inputElement) {16    // TODO 自动生成方法存根17    return input.elements().toArray();18  }1920  public void dispose() {21    // TODO 自动生成方法存根22    if(input != null){23      input.setListener(null);24    }25    input = null;2627  }2829  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {30    // TODO 自动生成方法存根31    viewer = (ListViewer)viewer;32    input = (PersonModel)newInput;33    input.setListener(this);3435  }3637  public void add(Person p) {38    // TODO 自动生成方法存根39    viewer.add(p);40  }4142  public void remove(Person p) {43    // TODO 自动生成方法存根44    viewer.remove(p);45  }4647}

我们知道,列表中的元素都是Person类的对象,怎么让他们显示出来呢,需要实现标签提 供器,在标签提供器中,我们可以设置对象显示的图标和文字,如下 PersonLabelProvider.java:

1package cn.blogjava.youxia.views;23import org.eclipse.jface.viewers.ILabelProvider;4import org.eclipse.jface.viewers.ILabelProviderListener;5import org.eclipse.swt.graphics.Image;67public class PersonLabelProvider implements ILabelProvider {89  public Image getImage(Object element) {10    return null;11  }1213  public String getText(Object element) {14    // TODO 自动生成方法存根15    return ((Person)element).getName();16  }1718  public void addListener(ILabelProviderListener listener) {19    // TODO 自动生成方法存根2021  }2223  public void dispose() {24    // TODO 自动生成方法存根2526  }2728  public boolean isLabelProperty(Object element, String property) {29    // TODO 自动生成方法存根30    return false;31  }3233  public void removeListener(ILabelProviderListener listener) {34    // TODO 自动生成方法存根3536  }3738}

运行程序,就得到了文章开头的效果,但是不能在右边的视图中显示病人的详细信息。

如果要做到视图的交互,需要添加事件的监听器。使用Java 进行GUI开发的人应该都不会 陌生,而我在RCP上,也处于探索阶段,更深一步的内容,让我们自己慢慢研究吧。

最重要的是今天的心。

使用EclipseRCP进行桌面程序开发(三):视图和透视图

相关文章:

你感兴趣的文章:

标签云: