wicket 详解

1.        ListView 

其实这个控件是用处最少的,也是最好决定的,如果数据很少,不需要分页,那么就是它了。小数据列表的不二之选,如购物网站上"你最近查看的n本书"。 

2.        PageableListView 

这是Wicket核心包中提供的一个分页控件,如果要分页操作,通常还需要一个PageNavigater。通常情况下,它不能够支持大量的数据列表,因为它是使用List作为数据源。所以在大数据量的情况下,不建议使用它。如果你一定要使用它,就可以象前面章节编写一个支持Lazy-Loading的DynamicList,这个List支持动态载入数据即可,这样就可以用来处理大数据量了,不过这种处理方式稍稍麻烦了一些,对程序员有较高的要求,所以建议正常情况下进行数据分页,请使用Wicket-Extensions包中提供的分页控件,也就是下面的几个控件。 

3.        RepeatingView 

事实上RepeatingView与ListView一样,用处不大,因为它内部有大量的操作要程序员自行实现,而且不支持分页。 

4.        DataView 

它给出了一个IDataProvider 作为数据源,这样就可以处理大量的数据,但是很可惜,还是要程序员自行处理每一行的输出。所以它也只是一个很基础的数据列表控件,但是因为由程序员来控制每一行的输出,所以也更加灵活。

5.        GridView 

其实GridView和DataView一样,都继承自DataViewBase这个类,功能上也没有大的区别,主要区别就是以下两点:

l        它可以强制设置表格的列数; 

l        对于空的单元格,它会提供newEmptyItem和populateEmptyItem两个方法,允许用户自行定义空单元格的处理方式。 

6.        DataGridView 

事实上前面所说的都只是数据列表控件,而现在所说的DataGridView才是一个真正的Table控件,它通过ICellPopulator接口来为每一个单元格来产生相应的数据。所以对于纯粹的数据列表而言,DataGridView最为合适。 

7.        DataTable 

DataTable与前几个不一样,上文中的列表控件通常是一个个继承下来的,如DataView和GridView都继承自DataViewBase,而DataTable直接继承自Panel。尽管它与DataGirdView并没有相应的继承关系,但是结构却非常相似,使用IDataProvider作为数据源,使用单元格数据生成器来填充单元格中的内容(DataGridView使用ICellPopulator,而DataTable使用IColumn)。 

经过上面的说明,可以得知,DataGridView和DataTable是功能最强大的两个列表控件,通常情况下,使用它们两个已经可以满足需要了,其它的控件,如果没有特殊情况,不建议使用。而DataGridView更适合用来以表格的方式查看数据,而DataTable则更适合以表格的形式来操作数据,如"编辑","删除"等。 

使用ibatis+wicket+spring开发才想到学一下WICKE,没关系有点基础抓起就学: 

1. Wicket组成:A.HTML+A.Java(extends WebPage)+AApplication(extends WebAppliction),AApplication对象在系统中主要管理相关信息的配置,主要方法是public Class getHomePage(){return A.class;} 
2. 通常情况下,Model是被用来为控件提供数据,控件只处理显示内容,而Model通过各种方式来提供所要显示的内容,这样 Model与控件就不存在耦合 
3. web.xml配置Web程序: 
<servlet> 
    <servlet-name>SomeApplication</servlet-name> 
    <servlet-class>wicket.protocol.http.WicketServlet</servlet-class> 
    <init-param> 
     <param-name>applicationClassName</param-name> 
     <param-value>AApplicationpath.AApplication</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>SomeApplication</servlet-name> 
    <url-pattern>/somepath/*</url-pattern> 
</servlet-mapping> 
4. Html和Java文件放在同一个Java包下面,名称也一定要相同,否则Wicket找不到相应的模板 
5.    Wicket控件是以Component为根的,它作为一个控制类解析Html文件以形成试图,并将Model中的数据正确的放入视图然后生成Html,最终输出到客户端. 
6. Wicket如何调用Listener: 
1) 有状态的URL:从一个Wicket页面转到另一个Wicket页面,此时原有的Wicket页面上的控件及相关信息都已经保存在Session中了,可以根据相应的参数从Session中取得Listener实例对象,进而调用相应的方法来完成工作,Url如下: 
/context/?param1=value1&wicket:interface=<pageMap>:<pageId>:<version> 
2) 无状态的URL:通过地址栏的一个链接URL来访问一个Wicket程序,信息并没有保存在Session中,要通过URL传入的参数来处理请求,如下: 
/context/?wicket:bookmarkablePage=mypackage.MyClassName&param1=value1&wicket:interface=<componentPath>:<listerInterface>,根据这个信息来转向相应的页面,再根据指明的componentPath来找到相应的控件,而litenerInterface则是指定了一个接口,该接口中所第一的那个无参方法将会被调用 
7. applicationClassName 是一个Wicket 提供的WebApplication 子类的类名全称。每一个WicketServlet 都需要一个该参数,这样在接到请求后,会将相应的请求转交给这个指定的类。然后由这个Application 真正的处理用户请求,WicketServlet 并不处理具体的用户请求,而是作为一个前端的Facade,负责分发用户请求。 
8. wicket的状态管理: 
默认情况下,为了方便管理状态,Wicket 提供了一个ISessionStore,并为其提供了一个默认实现HttpSessionStore,用来将控件的相关信息以及Model 保存在HttpSession 中,这样可以有效的对状态进行管理。 
      当用户对一个Wicket 应用程序发出请求,并要求回复一个Html 页面的时候,Wicket程序会按照预先的配置找到相应的Page,再使用该Page 输出Html 信息,此时该Page 对象会被放入一个PageMap,成为一个有状态的被管理对象。而这个PageMap 就会通过ISessionStore 被保存起来(默认情况是被保存到HttpSession 中)。PageMap 中放置的对象并不是无限的,必须进行数据更新,移除一些不必要的Page 对象,这样可以保证不占用过多的内存。Wicket 提供了一个PageMap 的管理策略接口 
wicket.session.pagemap.IPageMapEvictionStrategy,可以通过这个接口来配置PageMap的数据更新,可以通过WebApplication 的getSessionSetting来取得和设置这个策略的实现,而Wicket 则提供了一个按照最近使用原则更新数据的默认策略。在程序默认的配置下,PageMap中可以存放5个Page,可以通过重新设置策略来调整PageMap 的容量。 
9. wicket基本控件: 
1)信息输出控件 
(1)单行信息输出控件Label 
Label 是一个用来在网页上显示文字的控件,与通常C/S 程序中的Label 是一样的功能。如果表现在网页上,通常是使用<span>或者是<label>标签来声明这样一个控件。然后在Java 代码中使用相应的代码操作Label 控件。 
Label label =new Label("birthday","<span>message</span>"); 
label.setEscapeModelStrings(falsefalsefalse);//取消语义转义 
Label label =new Label("birthday","<span>message</span>"); 
label.setEscapeModelStrings(false); 
(2)多行信息输出控件MutlineLabel 
MultiLineLabel 的使用方法和Label 是一样的,两者其实没有太大的区别,只不过它可以将"\n"这种换行符号转换成<BR>从而实现换行。因为在Html 页面中,只认识<BR>。 

2) 控件容器 
(1)容器面板WebMarkupContainer 
WebMarkupContainer 继承自MarkupContainer,表明自身是一个可以容纳其它Wicket控件的Wicket 控件容器,它不需要一个HTML文件作为模板,所以可以直接在声明后使用。通常可以将同一类型的信息包含在一个WebMarkupContainer中,如果有必要的话,只需要掩藏这个WebMarkupContainer,就可以隐藏所有的控件了WebMarkupContainerWebMarkupContainer 
WebMarkUpContaier container= new WebMarkUpContaier("container"); 
this.add(container); 
container.add(newLabel("birthday","2006-09-09")); 

(2)合面板Panel 
Panel 继承自WebMarkupContainerWithAssociatedMarkup,而非WebMarkupConta除了表明自身是一个可以容纳其它Wicket 控件的Wicket 控件容器,另外也表示它需个相应的Html 文件来描述相应的控件。因此WebMarkUpContaier 作一个功能控件而出现(它不需要一个相应的Html)Panel 主要是作为一个基类出现,可以用来定义相应的Wicket 控件以及它们的布局,Panel可以实例化 

(3)边框控件Border 
其实Border在很大程度上与WebMarkupContainer没有任何区别,从字面上理解Border主要可以为一组控件提供边界显示,Wicket 小组要提供这个Border 控件也许是为了支持Swing吧。它继承自WebMarkupContainerWithAssociatedMarkup,与Panel 相似,需要相应的Html 文件。 
Border border=new BoxBorder("border"); 
this.add(border); 
border.add(new Label("birthday","2006-09-09")); 

(4)包含控件Include 
如果有几个页面都包含了相同的Html 代码,那么可以考虑将这些Html 代码放置在一个独立的Html 文件中,然后使用Include 控件包含这个Html 文件,Include 控件与Jsp中的Include 功能差不多,只过Jsp包含的include 是可以使用动态的Jsp 文件,而Wicket 的include 则只能使用静态的Html 文件。 
this.add(new Include("include","common.Html")); 

3)超链接控件 
(1)普通链接控件Link 
Wicket中的Link,不仅仅是可以链接到Wicket程序内部的页面,而且还是一个容器,可以包含Label,Image 等信息,点击Link 中的所有内容都会触发Link的链接事件。 
Link点击后,在服务器端可以通过onClick 来捕获点击事件,用来进行业务处理,如计数器等,还可以通过setResponsePage(new MyPage(obj.getId(), ...))进行页面转向。不过如果仅仅是进行页面转向,建议使用PageLink来进行页面转向,会更加方便和灵活。 
Link link =new Link("link") { 
public void onClick() { 
count++; 
} 
}; 
(2)外部链接控件ExternalLink 
Wicket 不仅仅支持程序内部的链接,而且还支持对外部的链接。通过使用 
ExternalLink这个控件,方便地连接到外部网站,这样的功能在做友情链接,或者商务合作时,是非常有用的。 
this.add(new ExternalLink("externalLink","http://www.sina.com.cn","新浪")); 

(3)页面链接控件PageLink 
在Wicket应用程序中,每一个链接最终指向的都是一个WebPage的实例。所以如果仅仅页面转向,建议使用PageLink。 
add(new PageLink("pageLink",new IPageLink() { 
public Page getPage() { 
return new MyPage(); 
} 
public Class getPageIdentity() { 
return MyPage.class; 
} 
})); 
(4)书签链接控件BookmarkablePageLink 
事实上每一个Application 都可以拥有多个WebPage,但只能有一个默认的WebPage。Wicket 通过Bookmark(书签)使一个Application能访问多个WebPage。 
PageParameters parameters =new PageParameters(); 
parameters.put("message","放置参数"); 
this.add(newnewnew BookmarkablePageLink("pageLink",LinkPage.class,parameters)); 

(5)文件下载链接DownloadLink 
文件下载链接分成两种,一种是静态的,如在网络目录下的文件,用户可以直接访问该文件,还有一种是动态的内容,比如为了安全,文件存放在用户不可见的本地目录中。前者可以直接在链接中写入地址,方便用户下载,而后者,则要通过流的方式来写回客户端以实现下载。Wicket 提供了一个 DownloadLink 的链接控件来处理后者,方便程序员开发此类应用。 
File file=File.createTempFile("new",".txt"); 
this.add(new DownloadLink("downloadLink",file)); 

(6)弹出窗口设置PopupSetting 
其实弹出窗口并不是一个确定的控件,它是通过一个PopupSettting 的配置类来描述弹出窗口的信息,然后在客户端的浏览器上生成相应的JavaScript 代码,然后点击该连接的时候,会弹出一个由配置指定信息的窗口 
BookmarkablePageLink popupLink =new BookmarkablePageLink("popupLink",SmartLinkPage.class); 
PopupSettings popupSettings =new PopupSettings(); 
popupSettings.setHeight(400); 
popupSettings.setWidth(400); 
popupLink.setPopupSettings(popupSettings); 

4)表单输入控件 
(1)表单控件Form 
Form 控件封装了Html 的Form标签,它不仅可以将服务端的信息显示成客户端Html代码,而且还可以对客户端提交的数据进行验证。一个表单被提交以后,会调用Form 对象实例的onSubmit 方法来进行业务处理,但在 
该方法被调用以前,Wicket还会进行一些额外的处理,包括数据验证,更新Model中的数据。如果用户指定了使用Cookie,可能还会更新Cookie 中的内容,最后才会调用这个onSubmit 方法,也就是说只有在所有的数据都被验证通过以后,而且相应上下文环境被正确设置以后,onSubmit 才会被调用,不会形成脏数据。 
Form form=new Form("form") { 
protected void onSubmit() { 
// 这里用来进行Form提交后的业务处理 
} 
}; 
form.add(...); 
// 在这里添加表单中的输入控件 
this.add(form); 
(2)信息输出控件FeedbackPanel 
表单在被提交以后,通常需要验证信息,并根据错误类型输出错误信息,方便用户正确输入数据。为了输出错误信息,Wicket 提供了一个FeedbackPanel 控件来处理相关的信息。它其实并不是Form的一部分,只不过它主要被Form所使用,所以也将它放在这里进行说明。 
this.add(new FeedbackPanel("feedback")); 
Form form=new Form("form") { 
protectedvoid onSubmit() { 
info("the formwas submitted!"); 
// 这里用来在FeedbackPanel输出信息 
} 
}; 
form.add(...) 
// 在这里添加表单中的输入控件 
this.add(form); 

(3)Button控件 
Form 必须在提交以后,才能向服务器端进行数据传输(可以直接使用<input 
type="submit" value="submit">)。如果想使用更灵活的方式来提交表单,Wicket 也提供了对Button 的支持,而且Wicket 的Button并不仅仅只是用来提交表单数据,还可以完成更多的功能,象Link等,事实上,当点击了一个Form 中的Button以后,它会先提交数据,由Form 来调用 
onSubmit 方法处理数据,然后再根据相关的参数来调用指定Button 的onSubmit 事件。这个转换操作是通过Form 的delegateSubmit 方法来进行处理的,如果想修改这一个逻辑处理,就重载这个方法。Wicket 的Button 中另外提供了一个setDefaultFormProcessing(boolean)方法。默认值为true,也就是在默认情况下,会先调用Form 的onSubmit 方法,然后才调用Button自身的onSubmit 方法。 
Button button2 =new Button("button2") { 
protected void onSubmit() { 
info("button2.onSubmit executed"); 
} 
}; 
button2.setDefaultFormProcessing(false); 

(4)图片按钮ImageButton 
ImageButton与Button并没有什么质的区别,只是显示的不是文字而是图片而已,它的事件调用与Button 相同,而其它的内容可以参考Image。 

(5)提交链接SubmitLink 
在Html 页面中,提交表单很多时候不一定要通过Button来提交,可能是通过JavaScript 来提交Form。所以Wicket提供了一个SubmitLink控件,它同样可以提交一个表单,它的特点在于,这个控件可以放置在表单的内部,也可以放置在表单的外部,这样就更加灵活了。如果在一个表单的外部来使用一个SubmitLink,为这个SubmitLink 指定它要提交的Form,在内部使用时就不需要指定Form,但要将这个链接加入到Form 中。 
Form form=new Form("form"); 
add(form); 
SubmitLink internal =new SubmitLink("internal"); 
form.add(internal); 
// 这里在Form的内部添加一个Link 
SubmitLink external =new SubmitLink("external",form); 
add(external); 
// 这里在Form的外部添加一个Link 

(6)输入文本控件TextField 
TextField 对应着Html 上的<input type="text">,用户可以通过该控件输入数据。 
Form form=new Form("form"); 
this.add(form); 
form.add(new TextField("text")); 
form.add(new TextField("integer",Integer.class)); 

(7)支持数据必填的文本控件RequiredTextField 
其实这个控件与TextField 并没有什么大的区别,只不过它在内部初始化的时候就自动添加了一个RequiredValidator,能够自动验证相应的数据不为空。之所以提供这样一个类,主要还是方便程序员处理一些简单的数据验证,也可以通过调用TextField 的setRequired(true)来实现这个功能。 

(8)密码输入控件PasswordTextField 
PasswordTextField 对应着Html上的<input type="password">,用户可以通过该控件显示或者填写密码信息。 
(9)多行输入文本控件TextArea 
TextArea 对应着Html 上的<textarea>,用户可以通过该控件显示或者填写多行文本信息。 
(10)选择框控件CheckBox 
Checkbox 对应着Html 上的<input type="Checkbox">,可以通过该控件显示选择框。 
(11)多选框控件CheckBoxMultipleChoice 
事实上,选择框通常是多个出现,而不是单独出现,允许用户选择多个元素,所以Wicket 提供了个多选框控件来支持多个元素的选择。CheckBoxMultipleChoice 提供了一个IChoiceRender 接口,用来输出要显示的文字,你可以实现这样一个接口,来定制特定的文字信息。 
(12)增强的多选框控件 
在编写Web程序的时候,通常会使用表格来输出一个数据列表,并为每一行都提供了一个选择框,而且为了方便用户进行操作,通常还会提供一个选择框进行全选/取消全选的操作。为了方便此类程序的开发,Wicket 提供了一个增强的多选框。基本使用方法: 
首先使用一个CheckGroup来包含所有要全选/取消全选的CheckBox,然后再使用CheckGroupSelector 对Group中所有的CheckBox 进行客户端的全选/取消全选。 
(13)下拉框控件DropDownChoice 
(14)单选列表框控件ListChoice 
(15)多选列表框控件ListMultipleChoice 
(16)单选组合框控件RadioChoice 
(17)图像控件Image 
Wicket 所提供的Image 控件功能非常强大,不仅可以显示一个静态的图像,还可以在服务器端生成动态图像显示在客户端。这样就为图表的显示提供了方便的处理。使用静态图像必须提供一个已有的图像文件,而使用动态图像则只需要重载一个renderer 方法以动态输出图像。 
this.add(new Image("static","test.gif")); 
//在当前目录下放置一个test.gif文件 
add(new Image("dynamic",new RenderedDynamicImageResource(100, 100){ 
protected nboolean render(Graphics2D graphics) { 
graphics.drawString("测试",10,10); 
return true;} 
})); 
(18)文件上传控件FileUploadField 
文件上传是开发Web程序的一个难点,通常要利用各种组件,如Jakarta 提供的commons-upload 来上传文件。 
Wicket 提供了一个更加容易使用的文件上传控件。 
final FileUploadField fileUploadField =new FileUploadField("image"); 
Form form=new Form("form") { 
protected void onSubmit() { 
final FileUpload upload =fileUploadField.getFileUpload(); 
if (upload !=null) { 
try { 
upload.writeTo(new File("d:\\1.txt")); 
} catch (IOException e) { 
e.printStackTrace(); 
} 
} 
super.onSubmit(); 
} 
}; 
form.add(fileUploadField); 
form.setMultiPart(true); 
// 在Wicket中使用文件上传控件 
// 还要记住一定要调用setMultiPart(true)这个方法来允许文件上传 
form.setMaxSize(Bytes.kilobytes(1000)); 
// 如果你有文件大小的限制,通过setMaxSize来设置数值。 

5).数据列表控件 
Wicket提供了一个普通的数据列表控件ListView 和支持数据分页的列表控件PageableListView。 
(1)简单的数据分页控件ListView 
ListView 与我们前面使用的控件有很大的不同,一是因为它本身是控件容器,能够支持子控件;二是它的子控件是通过循环来加入的;第三就是它的子控件会具有相同的名称,从逻辑上来讲是相等的。所以它提供了一个populateItem 抽象方法,用户通过重载这个方法来循环加入子控件。ListView 可以与任何控件一起组合使用,通常是与表格一同出现,这是因为表格可以逐行处理数据。 
(2)支持数据分页的列表控件PageableListView 
大部分情况下,要显示的数据不会只有几条,而是成千上万条数据,难道要在一个页面上同时显示这么多数据吗?Wicket 提供了一个PageableListView,它支持数据分页处理另外为支持分页操作,它一般是与PagingNavigator 一起使用,后者为它来提供"上一页","下一页"等分页操作。 
6)日历控件DatePicker 
DatePicker 并不能单独存在,它除了自己以外,还需要一个TextField,它只是显示一张图片,用户在点击这张图片以后,会使用JavaScript 弹出一个日期选择框,允许用户选择一个日期,然后将用户选择的日期填充到预先设定的TextField 中。 
TextField dateField =new TextField("dateField",Date.class); 
this.add(dateField); 
this.add(new DatePicker("dateFieldPicker",dateField)); 
// 在DatePicker的构造函数,要传递一个TextField给它, 
// 这样,它才可以将选择的数据正确的填充到文本框中。 

10. 为控件添加Css 和JavaScript 
在Html 模板中通过<wicket:head>来添加CSS 样式信息 
在Java代码中通过AttributeModifier添加样式表::: 

11. Wicket的 Html标签 
wicket:id,<wicket:message>,<wicket:remove>,<wicket:link>,<wicket:panel>和<wicket:head>,<wicket:child>和<wicket:extend>

你可能感兴趣的:(框架,wicket)