GXT之旅:第二章:GXT组件(6)——定制组件
原创
©著作权归作者所有:来自51CTO博客作者茜茜770的原创作品,请联系作者获取转载授权,否则将追究法律责任
定制组件
在GXT,乃至GWT中,定制组件是非常普遍并且有用的。定制组件大致可以分为两种:第一种,修改一个现有组件的功能;第二种,封装一个或多个组件并且加入新的功能,使其成为一个新的组件。相对于GXT而言,GWT有一个复合组件的概念——通过把一个组件包装到另外一个组件之上,从而达到定制组件的效果。但是GXT如果想实现这种复合组件会发生很多问题!
比如前面所用到的ContentPanel,用于RSSReader项目的west导航区。当把ContentPanel生成的对象放入west区显示的时候,同时也设置了其可折叠功能。但是如果基于ContentPanel创建一个复合组件的话,那个折叠功能的按钮就再也不会出现了。
原因是,当你要创建一个复合组件的话,那些public API方法就会不可见。GXT的设计理念是,如果要把几个组件复合成一个新的组件的话,就视为你怀疑GXT components自带的功能,既然如此那么这些功能就做废掉了,你将无法使用它们。
综上所述,GXT制定组件的最佳方法就是继承某个Component,然后直接或间接的使用其他的components。
onRender()
在开始定制组件之前,要再介绍一个非常重要的方法onRender()。当你继承某个component的时候,可选择是否覆盖(override)onRender()方法。这一机制得追溯于先前提到的GXT的“懒渲染”概念。
当一个component在初始化的时候,他的构造函数内的所有代码都会被执行;类似的,当一个component被渲染的时候,onRender()方法内的代码也会被执行。
根据此理论,我们可以很灵活的把需要立即执行的代码写在当前component的构造函数理,把需要在当前component被渲染之后,再执行的代码写在onRender()方法里。按照如此的编程思想,可以很好的提高GXT应用程序的性能和效率。
现在,我们就开始在RSSReader项目上,开始第一个定制组件——把原先应用在west导航区和center内容区的两个ContentPanels,替换为自定义的components。(随着RSSReader项目开发,我们将加入更多的定制组件)
- 在RSSReader项目里,新建package:com.danielvaughan.rssreader.client.components;再在此包下,新建RssNavigationPanel类,继承ContentPanel。作为west导航区域显示的内容。
package com.danielvaughan.rssreader.client.components;
import com.extjs.gxt.ui.client.widget.ContentPanel;
public class RssNavigationPanel extends ContentPanel
{
public RssNavigationPanel()
{
setHeading("Navigation");
}
}
- 同样的,新建RssMainPanel类,作为center内容区显示的内容。仅仅设置一下题头而已。
package com.danielvaughan.rssreader.client.components;
import com.extjs.gxt.ui.client.widget.ContentPanel;
public class RssMainPanel extends ContentPanel
{
public RssMainPanel()
{
setHeading("Main");
}
}
- 接下来,在RSSReader类的onModuleLoad()方法中,用新建的两个定制components替换原来的ContentPanels
package com.danielvaughan.rssreader.client;
import com.danielvaughan.rssreader.client.components.RssMainPanel;
import com.danielvaughan.rssreader.client.components.RssNavigationPanel;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class RSSReader implements EntryPoint {
/**
* This is the entry point method.
*/
@Override
public void onModuleLoad() {
Viewport viewport = new Viewport();
final BorderLayout borderLayout = new BorderLayout();
BorderLayoutData northData = new BorderLayoutData(LayoutRegion.NORTH,
20);
northData.setCollapsible(false);
northData.setSplit(false);
HTML headerHtml = new HTML();
headerHtml.setHTML("<h1>RSS Reader</h1>");
viewport.add(headerHtml, northData);
BorderLayoutData centerData = new BorderLayoutData(LayoutRegion.CENTER);
centerData.setCollapsible(false);
BorderLayoutData westData = new BorderLayoutData(LayoutRegion.WEST,
200, 150, 300);
westData.setCollapsible(true);
westData.setSplit(true);
RssMainPanel mainPanel = new RssMainPanel();
RssNavigationPanel navPanel = new RssNavigationPanel();
viewport.add(mainPanel, centerData);
viewport.add(navPanel, westData);
viewport.setLayout(borderLayout);
RootPanel.get().add(viewport);
}
}