欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

wicket 详解

程序员文章站 2022-07-15 15:14:09
...
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>