我想,我们经常会遇到一个问题,那就是如何根据实际情况在某一个界面上显示不同的控件或者一个做好的页面。举个例子来说,点击Button1,显示一个Combo,执行Action2,显示一个TableViewer。所有这一切都发生在一个窗体内,那应该怎么做呢?现在就给一个方法:使用PageBook。
PageBook是一个Composite的子类,但是在PageBook中,已经定义了自己的Layout--PageBookLayout,这一个布局类在Eclipse3.2中是公共类,这是一个Issue,可能在新版本中会加以更新,但是这不是我们需要关心的事情,我们只要知道对于PageBook来说设置Layout是没有意义的就可以了,所以我们不要使用setLayout这个函数了。但是,它还是可以设置LayoutData的,因为这个函数是和父组件的布局有关;
现在我们来看看到底使用PageBook需要注意什么问题。
1、要想使用PageBook显示我们的页面内容,这一页面内容必须是从PageBook构造出来的一个Control子类;否则的话调用PageBook的showPage函数是不会有任何反应的。爬Eclipse的源码,我们可以发现在showPage函数中有:
if (page.getParent() != this) {
return;
}
其中page是PageBook将要显示的page,它必须是Control类的子类,由此我们可以知道从PageBook构造一个page是必须的。
2、page的布局必须和page中需要显示的控件的布局相匹配,否则的话可能只显示了page而不能显示其中的内容;这一点好像不好理解,我们可以通过下面的例子说明;
3、PageBook是可以与其他控件共存于其父组件之内的,这样就保证了更加灵活的显示;
好下面用例子来说明它的使用吧:
首先是我们的命令Action:
action = new Action("Action") {
public void run() {
//需要说明的是PageBook存在于某一个ViewPart中,这一步是获得这个ViewPart,当然这不是必须的,它可以存在于其他的地方;
IViewPart viewpart = (UIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences()
[0].getView(true));
View view = (View) viewpart;
//这一步是以PageBook为parent,构建一个composite;
Composite composite = new Composite(view.getBook(), SWT.NONE);
//composite的布局是FillLayout,横向、纵向扩展
composite.setLayout(new FillLayout(SWT.HORIZONTAL | SWT.VERTICAL));
//page是我们想显示的内容,它有一个createControl(Composite parent)方法;
Page1 page = new Page1();
//page的parent被设定为composite,这样我们需要显示的内容就与PageBook联系起来了;
page.createControl(composite);
//调用showPage方法,需要注意的是,给定的参数必须是PageBook的那个直接的子类;
view.getBook().showPage(composite);
}
};
然后,是我们想显示的内容的createControl方法:
public void createControl(Composite parent) {
//container布满整个parent
Composite container = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
layout.verticalSpacing = 10;
container.setLayout(layout);
container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
//以下是我们的具体内容,它们都建立在container上
final Label label = new Label(container, SWT.NONE);
label.setText("System");
label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
label.setBounds(140, 132, 100, 20);
final Group helloGroup = new Group(container, SWT.NONE);
helloGroup.setText("Hello");
final GridData gd_helloGroup = new GridData(SWT.FILL, SWT.FILL, true, true);
helloGroup.setLayoutData(gd_helloGroup);
helloGroup.setLayout(new GridLayout());
}
最后,PageBook与其他控件共存与其parent组件上,这个函数存在于ViewPart中,当然这不是必须的:
public void createPartControl(Composite parent) {
parent.setLayout(new GridLayout(2, false));
book = new PageBook(parent, 0);
book.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Button button = new Button(parent, SWT.NONE);
button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
button.setText("Button");
}
除了以上的例子之外,我们还可以直接将想显示的内容构建在PageBook之上,但是这个时候我们需要在第二步中返回一个Control,不妨我们就返回container就行,这就要修改一下第二步的函数原型:public Control createControl(Composite parent) ,然后在第一步中得到这个Control然后再调用showPage函数,显示container即可。
如果,你试了半天也没有显示,多半的原因是Layout没有匹配;好好调整一下就行了,再不济,拷贝上面的代码,保管好用;
刚刚我又试了一下关于PageBook和其他的组件共同存在于其父组件之上的实现,换句话说就是在父组件上既有其他的组件又有PageBook,然后PageBook中的内容按照要求显示,如果仅仅套用上面给的例子,将会出现“当窗口改变大小时,由于Layout不匹配而将窗口挤坏的情况”,所以在这个时候还是采用第二种方法为好,我会继续研究第一种方法,然后看看是哪里的布局不匹配;