博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于SmartGwt的分页组件
阅读量:6843 次
发布时间:2019-06-26

本文共 11645 字,大约阅读时间需要 38 分钟。

  hot3.png

        最近发现oschina不给我发每周精彩回顾了,才想起距离上次写东西已经有9个月了,于是狠狠的惭愧了一把。程序员光干活,不总结是不行的,于是便跟大家分享下下面这些开发体验。

        最近公司的外网项目,都准备用Gwt开发,经过之前的一些试验,公司决定采用SmartGwt 2.4作为前台框架。经过一段使用之后,感觉SmartGwt基本上比较容易上手。不过,虽然他的showcase的例子挺丰富,但只覆盖了很少的api,所以基本上还是天天翻着api来开发。

        其组件库涵盖了绝大多数常见的控件,但是没有分页条,居然少了这么常用的组件,着实让人遗憾。先google了一下,没有令人满意的现成的扩展组件,查了半天,只在一个英文论坛里,发现一个半成品,只是个实现了部分页面展示逻辑的页面组件,而且没有数据交互。无奈,找不到现成的,只能自己动手丰衣足食了。

 

一、定义分页条功能

 

功能至少要满足基本需要。

比如对于用户来说,页面功能应该包括:

1、能够定位数据到:首页,上一页,下一页,末页

2、能够展示当前页和总页数

3、直接跳转到指定页(大于零,小于总页数)

4、根据当前页和总页数,控制按钮可用状态

对于程序员来说,这个组件应该可以:

1、方便的初始化工具条组件并能绑定数据展示组件(比如grid

2、定制每页记录数

3、最好和数据查询方法分离,消除对业务查询方法的依赖

4、最好能有个模态遮罩,在数据加载过程中,给予提示,同时限制用户的重复操作。

 

二、代码实现

 

经过分析和简单的设计,决定通过两个类来实现:

1、一个纯页面组件,继承自com.smartgwt.client.widgets.toolbar.ToolStrip。代码实现思路就不写了,反正是从混沌到清晰的一个过程。直接帖代码了

  

import com.smartgwt.client.types.Alignment;import com.smartgwt.client.types.Overflow;import com.smartgwt.client.util.SC;import com.smartgwt.client.widgets.Canvas;import com.smartgwt.client.widgets.IButton;import com.smartgwt.client.widgets.Label;import com.smartgwt.client.widgets.events.ClickEvent;import com.smartgwt.client.widgets.events.ClickHandler;import com.smartgwt.client.widgets.form.DynamicForm;import com.smartgwt.client.widgets.form.fields.TextItem;import com.smartgwt.client.widgets.grid.ListGrid;import com.smartgwt.client.widgets.grid.ListGridRecord;import com.smartgwt.client.widgets.toolbar.ToolStrip;/** *  * 分页工具条 *  * 使用方法: * 1、实例化一个分页工具栏,传入每页记录条数和绑定的grid * 2、实现一个ListGridDataControl(实例化方法参见类中注释,注意和分页工具的相互调用),并把它设值给分页工具栏的dataControl属性, *    注意:分页工具条和ListGridDataControl需要紧密配合相互调用。 * 3、调用active()方法,激活分页条并加载grid数据 *  * 提示: * 1、本分页工具不处理grid的行号,行号理解为grid的列定义范畴 * 2、可以多次调用active()方法,调用的结果相当于把分页栏定位到首页,并重新获取总页数 * 3、如果查询业务数据的参数改变时,可以重新实现并设置ListGridDataControl,然后调用active() * 4、可以调用setMaskMessage()设置遮罩的提示信息,如果不设置,采用默认值 *  * 说明: * 之所以需要ListGridDataControl回调分页工具条的方法,导致增加了相互依赖,主要是考虑到获取数据和获取记录总数的方法通常是异步的, * 为保持操作的同步性,只能通过互相调用的方式保持工具条和grid的正常工作。 *  * @author weichao * @version 1.0 */public class GridPaginationBar extends ToolStrip{	/**	 * 模态遮罩	 */	ModalWindow mask;		private String maskMessage = " 数据加载中...... ";	public void setMaskMessage(String maskMessage) {		this.maskMessage = maskMessage;	}	/**	 * 每页条数	 */	private int pageSize = -1;		/**	 * 当前页	 */	private int pageNum = -1;		/**	 * 总页数	 */	private int totalPage = -1;		/**	 * 数据记录条数	 */	private int totalRowNum = -1;		/**	 * 绑定的grid	 */	private final ListGrid grid;		//首页 	TopImgButton first = new TopImgButton(16,16,"/img/control_start_blue.png","/img/control_start.png");		//上一页	TopImgButton backward = new TopImgButton(16,16,"/img/control_rewind_blue.png","/img/control_rewind.png");		//下一页	TopImgButton forward = new TopImgButton(16,16,"/img/control_fastforward_blue.png","/img/control_fastforward.png");		//末页	TopImgButton last = new TopImgButton(16,16,"/img/control_end_blue.png","/img/control_end.png");			//输入框form	DynamicForm pageForm;		//页码输入框	protected TextItem pageText;		//转到按钮	IButton go = new IButton("转到");		//总页数	protected Label totalLabel;		//grid数据控制器	private ListGridDataControl dataControl;		public void setDataControl(ListGridDataControl dataControl){		this.dataControl = dataControl;	}		public GridPaginationBar(ListGrid listGrid, int pageSize) {		this(listGrid, pageSize,null);	}	/**	 * 	 * 构造方法中,只初始化工具条元素和事件,不初始化数据,	 * 构造完成后工具条处于禁用状态,需要首先传入grid数据控制器,	 * 然后调用active()方法来激活工具条,并开始加载数据。	 * 	 * @param listGrid 绑定的grid	 * @param pageSize 每页记录条数	 * @param maskCanvas 加载数据过程中,需要用遮罩遮盖的控件,如果传入null,则默认遮盖的对象为绑定的grid	 */	public GridPaginationBar(ListGrid listGrid, int pageSize, Canvas maskCanvas) {		this.grid = listGrid;		mask = new ModalWindow(maskCanvas == null ? grid : maskCanvas);		mask.setLoadingIcon("/img/loading.gif");		this.pageSize = pageSize;		first.setButtonTip("首页");		first.setButtonClickHandler(new ClickHandler(){			public void onClick(ClickEvent event) {				goToPage(1);			}		});		backward.setButtonTip("上一页");		backward.setButtonClickHandler(new ClickHandler(){			public void onClick(ClickEvent event){				goToPage(pageNum - 1);			}		});		pageText = new TextItem();		pageText.setWidth(40);		pageText.setHeight(20);		pageText.setShowTitle(false);		pageText.setTextAlign(Alignment.RIGHT);		go.setWidth(34);		go.setHeight(20);		go.addClickHandler(new ClickHandler(){			public void onClick(ClickEvent event) {				String page = pageText.getValueAsString();				if(page == null || page.trim().equals("")){					SC.say("请输入页码");					return ;				}else {					try{						int pageint = Integer.valueOf(page);						if(pageint<1){							SC.say("输入的页码不能小于1");							return;						}else if(pageint>totalPage){							SC.say("输入的页码不能大于总页数 "+totalPage);							return;						}else {							goToPage(pageint);						}					}catch(NumberFormatException e){						SC.say("请输入整数");						return;					}				}			}});				forward.setButtonTip("下一页");		forward.setButtonClickHandler(new ClickHandler(){			public void onClick(ClickEvent event){				goToPage(pageNum + 1);			}		});		last.setButtonTip("末页");		last.setButtonClickHandler(new ClickHandler(){			public void onClick(ClickEvent event){				goToPage(totalPage);			}		});		totalLabel = new Label();		totalLabel.setWrap(false);		totalLabel.setWidth(50);		setHeight(20);		setOverflow(Overflow.VISIBLE);		setStyleName("normal");		this.setMargin(5);		pageForm = new DynamicForm();		pageForm.setNumCols(1);		pageForm.setWidth(45);		pageForm.setItems(pageText);		Label blank1 = new Label();		blank1.setContents(" ");		blank1.setWidth(5);		blank1.setHeight(20);		Label blank2 = new Label();		blank2.setContents(" ");		blank2.setWidth(5);		blank2.setHeight(20);		Label blank3 = new Label();		blank3.setContents(" ");		blank3.setWidth(15);		blank3.setHeight(20);		Label blank4 = new Label();		blank4.setContents(" ");		blank4.setWidth(5);		blank4.setHeight(20);				Label blank5 = new Label();		blank5.setContents(" ");		blank5.setWidth(5);		blank5.setHeight(20);				addMember(first);		addMember(blank1);		addMember(backward);		addMember(blank2);		addMember(pageForm);		addMember(go);		addMember(blank5);		addMember(forward);		addMember(blank4);		addMember(last);		addMember(blank3);		addMember(totalLabel);		setAlign(Alignment.RIGHT);		resetPaginationState();	}	/**	 * 转到指定页,获取分页数据并装载,	 * 获取数据过程中,加模态遮罩	 * 	 * @param pageNum	 */	public void goToPage(int pageNum) { 		go.disable();		if (pageNum > totalPage)			pageNum = totalPage;		if (pageNum < 1)			pageNum = 1;		if (pageNum == this.pageNum) {			go.enable();			return;		}		mask.show(maskMessage, true);		//fetch data and reload grid		this.pageNum = pageNum;		int startNum = (pageNum - 1) * pageSize;		dataControl.fetchData(startNum, pageSize);			}	/**	 * 根据记录总数计算总页数	 */	private void countTotalPages()	{		if(totalRowNum < 1){			totalPage = -1;			return;		}		int pages = (int) Math.ceil(((float) totalRowNum) / ((float) pageSize));		// never return zero pages		if (pages == 0)			pages = 1;		this.totalPage=pages;		pageNum = 1;	}		/**	 * 首次查询数据,获取数据总数等信息,并更新分页条状态	 * 获取数据过程中,加模态遮罩	 */	public void active(){		if(dataControl == null){			SC.say("错误","分页栏未配置ListGridDataControl数据控制器,请检查代码");			return;		}				//首先禁用工具条		if(pageNum != -1){			resetPaginationState();		}		mask.show(maskMessage, true);		dataControl.getTotal();			}		/**	 * ListGridDataControl获取总记录数后的回调方法	 * @param all	 */	public void afterGetTotal(int all){		this.totalRowNum = all;		countTotalPages();		if(totalPage==-1){			//如果没有查询到数据,则清空原来的数据			afterFetchData(new ListGridRecord[0]);		} else {			dataControl.fetchData(0, pageSize);		}			}		/**	 * ListGridDataControl获取数据后的回调方法	 * @param datas	 */	public void afterFetchData(ListGridRecord[] datas){		if(datas != null){			dataControl.loadData(datas);		}		updatePageinationState();		mask.hide();	}		/**	 * 清除分页工具条状态,全部置灰,不负责清空grid当前数据	 */	private void resetPaginationState(){		pageNum = -1;		totalPage = -1;		totalRowNum = -1;		first.disable();		backward.disable();		last.disable();		forward.disable();		pageText.disable();		go.disable();		totalLabel.setContents("");	}	/**	 * 依据当前页和总页数控制工具条状态	 * 规则:	 * 		当前页为-1,则说明工具条尚未激活或者没有查询到数据,不需要处理;	 *		当前页等于1,则首页按钮和上一页按钮置灰,否则,激活;	 * 		当前页等于总页数,则末页按钮和上一页按钮置灰,否则,激活;	 */	private void updatePageinationState() {		if(pageNum==-1||totalPage==-1){			return;		}		totalLabel.setContents("第" + pageNum + "页/共" + totalPage + "页");		pageText.enable();		go.enable();		pageText.setValue(pageNum);		if (pageNum == 1){			first.disable();			backward.disable();		} else {			first.enable();			backward.enable();		}		if (pageNum == totalPage){			last.disable();			forward.disable();		} else {			last.enable();			forward.enable();		}	}}

 

2、一个控制接口类

即GridPaginationBar 类里的ListGridDataControl ,代码如下:

 

import com.smartgwt.client.widgets.grid.ListGridRecord;/** *  * @author weichao * listGrid数据获取及装载接口 ,和工具条有紧密的相互调用 * grid加分页工具条时,需要实现此接口并提供给分页工具条 *  *  * 示例: *  * GridPaginationBar pageBar = new GridPaginationBar(bizGrid,20,bizGrid.getParentElement()); *  * pageBar.setDataControl(new ListGridDataControl(){ *			public void fetchData(int start, int pageSize) { *				service.getBusiness(sid,start,pageSize, *		                new AsyncCallback
>() { * public void onFailure(Throwable caught) { * Window.alert(caught.getMessage()); * } * public void onSuccess(List
result) { * list = result; * pageBar.afterFetchData(RenderBizData.getNewRecords(result)); * } * }); * } * public void getTotal() { * service.getBusinessTotal(sid, new AsyncCallback
(){ * public void onFailure(Throwable arg0) { * Window.alert(arg0.getMessage()); * } * public void onSuccess(Integer arg0) { * pageBar.afterGetTotal(arg0); * }} ); * } * public void loadData(ListGridRecord[] records) { * bizGrid.setData(records); * }}); */public interface ListGridDataControl { /** * 获取分页数据,并回调分页工具栏的afterFetchData()方法, * 如果需要异步获取数据,请注意回调afterFetchData()的时机,保持数据的同步操作。 * * @param start * @param pageSize */ public void fetchData(int start,int pageSize); /** * 获取数据记录总数,并回调分页工具栏的afterGetTotal()方法 * 如果需要异步获取数据,请注意回调afterGetTotal()的时机,保持数据的同步操作。 * * @return 总数 */ public void getTotal(); /** * 把数据装载入grid * @param records */ public void loadData(ListGridRecord[] records);}

 

3、从网上找了个模态窗口ModalWindow ,直接使用了,这里就不贴代码了:

需要的可以从这里找

 

4、TopImgButton类是自己实现的一个按钮类,当然你可以用smartgwt的按钮 ,或者你自己写个。

import com.smartgwt.client.types.Cursor;import com.smartgwt.client.widgets.Img;import com.smartgwt.client.widgets.events.ClickHandler;import com.smartgwt.client.widgets.layout.HLayout;/** * @author weichao * 有激活和置灰两种状态的图片按钮 */public class TopImgButton extends HLayout{	Img enable = new Img();	Img disable = new Img();	private boolean _enable = true;	public TopImgButton(int buttonWidth,int buttonHeight,String enableImgSrc,String disableImgSrc){		setWidth(buttonWidth);		setHeight(buttonHeight);		enable.setSrc(enableImgSrc);		enable.setWidth(buttonWidth);		enable.setHeight(buttonHeight);		enable.setCursor(Cursor.POINTER);		disable.setSrc(disableImgSrc);		disable.setWidth(buttonWidth);		disable.setHeight(buttonHeight);		addMember(enable);	}		public void enable(){		if(!_enable){			removeMember(disable);			addMember(enable);			_enable = !_enable;		}	}		public void disable(){		if(_enable){			removeMember(enable);			addMember(disable);			_enable = !_enable;		}	}		public void setButtonClickHandler(ClickHandler handler){		enable.addClickHandler(handler);	}		public void setButtonTip(String tipMessage){		enable.setTooltip(tipMessage);	}}

三、效果

 

注释里写的比较多了,还有示例也帖在类的注释里了,所以就不再解释怎么用了。

经过几番测试,感觉运行比较稳定。希望能对需要smartgwt分页的朋友有所帮助。

转载于:https://my.oschina.net/jawava/blog/28799

你可能感兴趣的文章
同是ZooKeeper,你和架构师的理解差在哪里?
查看>>
你的心情如何?镜头「读脸」读出你的心情与隐私之间
查看>>
【更新指南】BarTender正式迎来2019 R2重大版本更新!
查看>>
2019年在哪里找好的高层次人才扶持政策?
查看>>
解决代码报红:Cannot resolve symbol 'xxx'
查看>>
第71节:Java中HTTP和Servlet
查看>>
Linux开源CommunityBridge平台 提供资金、安全以及人员三项关键
查看>>
Python爬虫入门教程 5-100 27270图片爬取
查看>>
Day1:html和css
查看>>
开源如何在云上存活?
查看>>
Android 网络基础之 HTTP
查看>>
ES6实现继承
查看>>
有擎企业系统v1.0.0 积木式搭建网站,页面构建更灵活
查看>>
小葵花妈妈课堂开课了:《Handler Looper Message 浅析》
查看>>
【Electron】酷家乐客户端开发实践分享 — 入坑篇
查看>>
浅谈Git、Github、码云的关系
查看>>
Cocos2dx源码记录(7) CCGLProgramState
查看>>
微信小程序实现商城案例(赋源码)
查看>>
Objective-C内存管理
查看>>
new xxx(),arr.map(),window.open(href),str.replace('a','b')
查看>>