当前位置: 代码迷 >> Web前端 >> Wicket的学习(1)
  详细解决方案

Wicket的学习(1)

热度:284   发布时间:2012-08-25 10:06:20.0
Wicket的学习(一)

?

今天我将具体的说明wicket到底是什么,以及自己的学习心得

1.官网

http://wicket.apache.org/

目前版本为1.5.3

2.Hello World 的例子:

我已经写过了wicket的HelloWorld,很简单,基本就是一个WebPage,一个WebApplication,还有一个Html

具体的下面链接:

HelloWorld:

http://wicket.apache.org/learn/examples/helloworld.html

Page to Page:

http://chenhailong.iteye.com/admin/blogs/1319936

这个比较复杂,但也看懂了就很简单了

?

Wicket MVC结构:

Model 数据层

View 默认为XHTML模板

Controller Application和Component类来处理

?

Wicket如何处理用户请求

入口:WebApplication

中间件:Session->RequestCycle->Request->ResponsePage

出口:Response

?

RequestCycle的处理过程:

Request->prepare->requestTargets.push(处理队列)->processEventAndResponse->Response(WebPage->renderPage)

?

WebPage处理过程:

WebPage->VisitChildren(Models)->inner Model->input render

?

wicket1.5.3基本组件:

Output:Label,MultiLineLabel,alternative markup

layout and grouping:

Panel,Border,Include,TabbedPanel,Fragment

Links:

Link,ExternalLink,PageLink,BookmarkablePageLink

Forms:

Form,Button,SubmitLink,TextField,TextArea,CheckBox,CheckGroup,

CheckBoxMultipleChoice,Palette,DropDownChoice,ListChoice,RadioChoice,

Radio,ListMultipleChoice,Select

?

细细分析

1.Label label = new Label("test", "<span>message</span>");

? label.setEscapeModelStrings(false);

?

? 对应HTML:

? <label wicket:id = "test" >I am a good man</label>

?

2.MultiLineLabel label = new MultiLineLabel("test");

? 对应HTML

? <span wicket:id ="test"><p>用户名称<br/>生日为</p></span>

?

? MultiLineLabel 控件并不是继承自Label 控件,而是直接继承自WebComponent。

?

3.<span wicket:id="panel">

<span wicket:id="birthday">在这里输出生日信息</span>

? </span>

? public class PanelPage extends WebPage {

public PanelPage() {

super();

Panel panel = new Panel("panel");

this.add(panel);

panel.add(new Label("birthday", "2006-09-09"));

}

? }

?

?

4.<H1>这里是我的版权声明,请不要随便修改我的资料啊!</H1>

? <html>

<body>

<span wicket:id="include"> 在这里放置通用的Html代码</span>

</body>

? </html>

? public class IncludePage extends WebPage {

public IncludePage() {

super();

this.add(new Include("include", "common.Html"));

}

? }

?

?

?

1.如何避免将Wicket 标签输出到客户端?

protected void init() {

super.init();

this.getMarkupSettings().setStripWicketTags(true);

}

setOutputMarkupId(false)方法禁止输出wicket:id这个标识

?

?

2.如何转向一个非Wicket页面

// 通知Wicket将要进行页面转向

getRequestCycle().setRedirect(false);

// 通知Wicket页面转向,不需要向客户端输出信息

getRequestCycle().setRequestTarget(EmptyRequestTarget.getInstance());

// 设定一个路径,并进行页面转向

String contextPath = getApplication().getApplicationSettings().getContextPath();

getResponse().redirect(contextPath + "/path/to/legacyJspFile.jsp"); ?

?

?

3.如何将字符串与URL 进行转换呢

Wicket 提供了灵活的数据转换功能,你只需要重载Component 的getConverter 方法就

可以在两种数据类型之间进行转换。这个方法是要返回一个IConvertor 的实现,用来实现

数据转换。

public Object convert(Object value, Class c) {

if (value == null) {

return null;

}

if (c == URL.class) {

(value.getClass() == URL.class) {

return value;

}

try {

return new URL(value.toString());

} catch (MalformedURLException e) {

throw new ConversionException("'" + value + "' is not a valid URL");

}

}

return value.toString();

}

我可以在Wicket使用Frame吗

在 Wicket 中使用Frame 其实是一个比较麻烦的问题,Tapestry 中也存在同样的问题,

经常出现"当前页面已经过期"。这是因为Wicket 是将所有的页面信息都保存在Session

中,默认保存5 个页面,如果客户端所请求的页已经不在Session 中,那么就会出现这样

一个错误。所以如果要使用Frame 的话,Wicket 建议通过参数方式来处理Frame,提供一

个pageMap 来指定Frame,还有就是尽量使用bookmarkablePage 参数来定义转向页面,也

建议多使用无状态页面,这样可以更加安全。

<Html>

<HEAD>

<TITLE>A simple frameset document</TITLE>

</HEAD>

<FRAMESET cols="20%, 80%">

<FRAMESET rows="100, 200">

<FRAME

src="myapp?pagemap=leftframe&bookmarkablePage=mypackage.MyNavigationPage">

<FRAME src="myapp?bookmarkablePage=mypackage.MyMainPage">

</FRAMESET>

<FRAME

src="myapp?pagemap=bottomframe&bookmarkablePage=mypackage.MyStatusBarPage">

</FRAMESET>

</Html>

我能够动态的指定Html 元素的某个属性值吗?

在做一个数据列表的时候,我希望根据奇偶行数显示不同的颜色,最好是通过样式表

来显示这一功能,即通过Html 属性class 来指定css 的名称。如何来动态的指定这个属性

值呢?

if (item.getIndex() % 2 == 1) {

item.add(new AttributeModifier("class", true, new Model("even")));

} else {

item.add(new AttributeModifier("class", true, new Model("odd")));

}

?

在前面基础控件介绍中,有一个增强的多选框控件,是否一定要提供一个

boolean 属性?

List list=(List)group.getModelObject();

//list中就是客户选择的数据记录

?

前一个例子中,使用了<wicket:remove>这个标签,编辑的时候,可以看到标签中的内

容,在输出的时候为什么没有了,它用来做什么啊?

?

<wicket:remove>并不是功能标签,它是一个声明标签,它是指Wicket 在输出Html

时,忽略其中的所有的内容。

Wicket 程序运行是动态的,所以运行一个列表的时候,通常只需要在一个表格行上加

上相应的wicket:id 就可以了,但是美工MM设计页面时是静态的,为了方便她们看到数

据,所以多写了一些表格行,但是这些内容在运行时并不需要,所以加上<wicket:remove>

标签声明,这样即方便了美工MM的工作,也不会对程序员开发Html 告成困扰。

?

我可以动态改变页面上的控件吗?

一、通过Wicket 提供的Panel 来解决问题:

首先准备两个Panel,一个是使用MultiRadioChoice 进行单选,还有一个则是使用

DropDownChoice 进行单选,可以在页面上声明一个Panel,然后根据可选项的情况来放置

不同的Panel。

if (jobs.size() > 5) {

this.add(new RadioChoicePanel("component", jobs));

} else {

this.add(new DropDownChoicePanel("component", jobs));

}

?

<wicket:panel>

<select wicket:id="jobs"></select>

</wicket:panel>

?

public class DropDownChoicePanel extends Panel {

public DropDownChoicePanel(String id,List jobs) {

super(id);

this.add(new DropDownChoice("jobs",jobs));

}

}

<wicket:panel>

<span wicket:id="jobs"></span>

</wicket:panel>

public class RadioChoicePanel extends Panel {

public RadioChoicePanel(String id, List jobs) {

super(id);

this.add(new RadioChoice ("jobs", jobs));

}

}

通过隐藏控件来解决这个功能:

public SingleComponentPage() {

super();

RadioChoice radioChoice = new RadioChoice("radioChoice", jobs);

DropDownChoice dropDownChoice = new DropDownChoice("dropDownChoice",

jobs);

this.add(radioChoice);

this.add(dropDownChoice);

if (jobs.size() > 5) {

dropDownChoice.setVisible(false);

} else {

radioChoice.setVisible(false);

}

}

我可以对数据验证时产生的错误进行排序吗?

你可以实现一个Comparator 接口,然后通过 setSortingComparator 方法设置这个

Comparator ,然后FeedbackPanel 可会通过这个Comparator 来对错误信息进行排序。

备注:传递给Comparator 的是FeedbackMessage,而不是String。

下面是一个简单的实例:

feedback.setSortingComparator(new Comparator() {

public int compare(Object o1, Object o2) {

FeedbackMessage m1 = (FeedbackMessage) o1;

FeedbackMessage m2 = (FeedbackMessage) o2;

return 1;

}

});

?

为什么我使用Tree 控件得到结果与书上写的不一样?

使用 extension 包中的Tree 控件,应该就不存在这个问题了,推荐方案!

?

WicketTester 进行单元测试

?

Application.getAjaxSettings().setAjaxDebugModeEnabled(false)关闭该调试功能

?

我一定要把Html 模板同Java 放置在一起吗?

不一定的,你可以将Html 模板放在任何一个目录下面,然后在Application 中配置相

应的文件路径,只要它的路径与Java 代码一致即可:

?

代码如下所示:

package org.wicket.demo.hello;

import wicket.protocol.http.WebApplication;

import wicket.util.file.Path;

public class HelloWorldApplication extends WebApplication {

protected void init() {

super.init();

this.getMarkupSettings().setStripWicketTags(true);

String path = "D:\\Program\\Eclipse\\Workspace\\Wicket\\Wicket\\src";

//这里放置Html模板的路径

Path resourcePath = new Path();

resourcePath.add(path);

this.getResourceSettings().setResourceFinder(resourcePath);

}

public Class getHomePage() {

return HelloWorldPage.class;

}

}

?

为什么会经常出现页面过期的问题?

void setMaxPageMaps(int maxPageMaps);

?

?

?