Click 是一个简单的商用JEE web程序框架,项目在遵从Apache license. 的
前提下开源。
Click 使用一个基于programming model 的事件来处理servlet请求。
使用Velocity来呈现页面。(其他的模板引擎如jsp和Freemarker也被支持)
此框架使用了一个单独的名为ClickServlet的servlet,来作为请求分发器。
当一个请求到来的时候,ClickServlet生成一个Page对象来处理请求并
使用Velocity模板来呈现结果 。
Pages 为每个servlet请求生成一个新的page实例,以此来
提供了一个简单的线程安全的设计环境,
可能的最好的学习Click如何工作的方式是练习一些例子。
Hello World - 经典的Hello World例子
Control Listener - 一个ActionLink控件监听器例子
Simple Table - 一个简单的Table控件例子
Advanced Table - 一个高级的Table控件例子
Simple Form - 一个简单的表单例子
Advanced Form - 一个复杂的表单例子
Hello World
一个使用Click的Hello World 例子如下所示
首先我们新建一个HelloWorld类
package examples.page;
import java.util.Date;
import net.sf.click.Page;
public HelloWorld extends Page {
public Date time = new Date();
}
建立一个page模板 hello-world.htm
<html>
<body>
<h2>Hello World</h2>
Hello world from Click at $time
</body>
</html>
最后建立一个click.xml配置文件,使用它来告诉Click将对
hello-world.htm 的请求映射到我们的HelloWorld类。
<click-app>
<pages package="examples.page"/>
</click-app>
在运行期间,ClickSerlvet 映射一个Get请求hello-world.htm 到
我们的page类example.page.HelloWorld , 并生成一个新的实例。
HelloWorld 生成一个新的public类型的Date对象, 并使用字段time
自动地将该对象添加到页面模型中。
页面模型使用Date对象替换掉模板中的$time , Velocity呈现模板页面
如下:
引用
Hello World
Hello world from Click at Tue May 08 19:37:05 EST 2007
Control Listener
Click包含一系列提供用户接口功能的控件。
ActionLink就是被广泛使用的其中之一, 你可以使用它在
一个Page对象中使一个链接调用一个方法。例如:
public class ControlListenerPage extends Page {
public ActionLink myLink = new ActionLink();
public String msg;
// ----------------------------------------------------------- Constructors
/**
* 生成一个新的Page实例
*/
public ControlListenerPage() {
myLink.setListener(this, "onMyLinkClick");
}
// --------------------------------------------------------- Event Handlers
/**
* 处理 the myLink 控件点击事件
*/
public boolean onMyLinkClick() {
msg = "ControlListenerPage#" + hashCode()
+ " object method <tt>onMyLinkClick()</tt> invoked.";
return true;
}
}
在这个Page类里我们生成了一个名为myLink 的ActionLink并定义
对应本页面的控件的监听器方法onMyLinkClick(),
当用户点击了MyLink控件,它将执行监听器方法onMyLinkClick()。
在Click中, 一个监听器方法可以起任何名字但必须返回一个布尔值。
该布尔值指定了下面的处理是否还要继续。
回到我们的例子中,在page模板中, 我们定义了一个HTML链接,
<html>
<head>
<link type="text/css" rel="stylesheet" href="style.css"></link>
</head>
<body>
Click myLink control <a href="$myLink.href">here</a>.
#if ($msg)
<div id="msgDiv"> $msg </div>
#end
</body>
</html>
在运行期间此页面将被呈现如下:
引用
Click myLink control
here.
当用户点击了link, onMyLinkClick()将被调用。 此方法生成了一个
msg模型值, 呈现如下:
引用
Click myLink control here.
ControlListenerPage#12767107 object method onMyLinkClick() invoked.
Simple Table Example
Table控件是最常使用的控件之一。
在客户端页面中使用Table控件的一个例子如下:
public class SimpleTablePage extends Page {
public Table table = new Table();
// ------------------------------------------------------------ Constructor
public SimpleTablePage() {
table.setClass(Table.CLASS_ITS);
table.addColumn(new Column("id"));
table.addColumn(new Column("name"));
table.addColumn(new Column("email"));
table.addColumn(new Column("investments"));
}
// --------------------------------------------------------- Event Handlers
/**
* @see Page#onRender()
*/
public void onRender() {
List list = getCustomerService().getCustomersSortedByName(10);
table.setRowList(list);
}
}
在此例子中, 一个Table控件被生成,我们设置了表格的html类,并
定义了一些列对象。在这些列定义中,我们在其构造方法中指定了
列的名字。
最后做的事情是使用数据来组装表格。 我们只需覆写Page的onRender()
方法并在表格显示前设置表格的列表。
在我们的页面模板中, 我们简单的引用了$table对象,当其toString()方法
被调用的时候,$table被呈现在页面上。
<html>
<head>
$cssImports
</head>
<body>
$table
</body>
</html>
$jsImports
在上面我们指定了$cssImports 引用, 以便表格在头部可以包含
css样式。同时我们在底部也定义了$jsImports来引用scripts 。
在运行期间, 表格将被呈现如下:
Advanced Table Example
Table控件还提供如下支持:
自动呈现
列格式化
自动分页
链接支持
一个更高级的Table例子如下:
public class CustomerPage extends Page {
public Table table = new Table();
public PageLink editLink = new PageLink("Edit", EditCustomer.class);
public ActionLink deleteLink = new ActionLink("Delete", this, "onDeleteClick");
// ------------------------------------- Constructor
public CustomersPage() {
table.setClass(Table.CLASS_ITS);
table.setPageSize(10);
table.setShowBanner(true);
table.setSortable(true);
table.addColumn(new Column("id"));
table.addColumn(new Column("name"));
Column column = new Column("email");
column.setAutolink(true);
column.setTitleProperty("name");
table.addColumn(column);
table.addColumn(new Column("investments"));
editLink.setImageSrc("/images/window-edit.png");
editLink.setTitle("Edit customer details");
editLink.setParameter("referrer", "/introduction/advanced-table.htm");
deleteLink.setImageSrc("/images/window-delete.png");
deleteLink.setTitle("Delete customer record");
deleteLink.setAttribute("onclick", "return window.confirm('Are you sure you want to delete this record?');");
column = new Column("Action");
column.setTextAlign("center");
AbstractLink[] links = new AbstractLink[] { editLink, deleteLink };
column.setDecorator(new LinkDecorator(table, links, "id"));
column.setSortable(false);
table.addColumn(column);
}
// ---------------------------------- Event Handlers
/**
* Handle the delete row click event.
*/
public boolean onDeleteClick() {
Integer id = deleteLink.getValueInteger();
getCustomerService().deleteCustomer(id);
return true;
}
/**
* @see Page#onRender()
*/
public void onRender() {
List list = getCustomerService().getCustomersByName();
table.setRowList(list);
}
}
在这个Page代码中,一个Table控件被声明并添加了一些Columns对象。一个
名为 deleteLink的 ActionLink被用做“Action”列的装饰器。当此控件被点击的时候
将执行onDeleteClick()方法。最后,当页面被显示的时候,调用onRender()方法
来使Table控件和列完成组装。
在我们的页面模板中我们简单引用 $table对象 , 当它的toString()方法被调用时,
$table对象被呈现出来。
<html>
<head>
$cssImports
</head>
<body>
$table
</body>
</html>
$jsImports
在运行期间,表格将被呈现的页面如下:
在这个例子中,如果用户点击了Delete链接, onDeleteClick()方法将被调用来
删除用户列。
(续)