今天我们来学习一下树控件的使用,如下图所示。最后要做出来的成果。勾选上面的勾选项,下面将会更新。
我们来看一下homepage.java实现代码,注意下面代码中使用到构建树的方式。对应的层级关系。
public class HomePage extends WebPage {
private static final long serialVersionUID = 1L;
private NestedTree<DefaultMutableTreeNode> tree;
public HomePage() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Cities of Europe");
addNodes(addNodes(root, "Italy"), "Rome", "Venice", "Milan", "Florence");
addNodes(addNodes(root, "Germany"), "Stuttgart", "Munich", "Berlin", "Dusseldorf", "Dresden");
addNodes(addNodes(root, "France"), "Paris ", "Toulouse", "Strasbourg", "Bordeaux", "Lyon");
DefaultTreeModel treeModel = new DefaultTreeModel(root);
TreeModelProvider<DefaultMutableTreeNode> modelProvider = new TreeModelProvider<DefaultMutableTreeNode>(treeModel) {
@Override
public IModel<DefaultMutableTreeNode> model(DefaultMutableTreeNode object) {
return Model.of(object);
}
};
tree = new NestedTree<DefaultMutableTreeNode>("tree", modelProvider)
{
private static final long serialVersionUID = 1L;
@Override
protected Component newContentComponent(String id, IModel<DefaultMutableTreeNode> model)
{
return new CheckedFolder<DefaultMutableTreeNode>(id, this, model);
}
};
//select Windows theme
tree.add(new WindowsTheme());
add(tree);
}
protected NestedTree<DefaultMutableTreeNode> getTree() {
return tree;
}
public static DefaultMutableTreeNode addNodes(DefaultMutableTreeNode parent, String... childrenNode){
DefaultMutableTreeNode newNode = null;
for (int i = 0; i < childrenNode.length; i++) {
newNode = new DefaultMutableTreeNode(childrenNode[i]);
parent.add(newNode);
}
return newNode;
}
}
来看一下homepage.html界面
<!DOCTYPE html>
<html lang="en" xmlns:wicket="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div wicket:id="tree"></div>
<br />
<div>
<wicket:link>
<a href="AdvancedCheckedTreePage.html">
Go to the advanced tree
</a>
<a href="HomePage.html">Go back to the home page</a>
</wicket:link>
</div>
<wicket:child />
</body>
</html>
下面我们来看一下AdvancedCheckedTreePage的代码
public class AdvancedCheckedTreePage extends HomePage {
public AdvancedCheckedTreePage() {
NestedTree<DefaultMutableTreeNode> tree = getTree();
RepeatingView selectedNodes = new RepeatingView("nodes");
final WebMarkupContainer markupContainer = new WebMarkupContainer("checkedNodes");
final Set<DefaultMutableTreeNode> checkedNodes = new HashSet<DefaultMutableTreeNode>();
tree = new NestedTree<DefaultMutableTreeNode>("tree", tree.getProvider())
{
SetModel<DefaultMutableTreeNode> checkedNodesModel = new SetModel<DefaultMutableTreeNode>(
checkedNodes);
@Override
protected Component newContentComponent(String id, IModel<DefaultMutableTreeNode> model)
{
return new AutocheckedFolder<DefaultMutableTreeNode>(id, this, model,checkedNodesModel);
}
};
tree.add(new AjaxEventBehavior("click") {
@Override
protected void onEvent(AjaxRequestTarget target) {
RepeatingView selectedNodes = new RepeatingView("nodes");
for(DefaultMutableTreeNode node :checkedNodes){
selectedNodes.add(new Label(selectedNodes.newChildId(), node.toString()));
}
if(checkedNodes.isEmpty())
markupContainer.setVisible(false);
else
markupContainer.setVisible(true);
markupContainer.replace(selectedNodes);
target.add(markupContainer);
}
});
//select Windows theme
tree.add(new WindowsTheme());
markupContainer.add(selectedNodes);
markupContainer.setVisible(false);
add(markupContainer.setOutputMarkupPlaceholderTag(true));
addOrReplace(tree);
}
}
对应的html界面
<html lang="en" xmlns:wicket="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<br/>
<wicket:extend>
<h2>Selected nodes will be displayed down here:</h2>
<div wicket:id="checkedNodes">
<ul >
<li wicket:id="nodes"></li>
</ul>
</div>
</wicket:extend>
</body>
</html>
每次点击后的重新刷新树的类
public class AutocheckedFolder<T> extends CheckedFolder<T> {
private ITreeProvider<T> treeProvider;
private IModel<Set<T>> checkedNodes;
private IModel<Boolean> checkboxModel;
public AutocheckedFolder(String id, AbstractTree<T> tree, IModel<T> model,IModel<Set<T>> checkedNodes) {
super(id, tree, model);
this.treeProvider = tree.getProvider();
this.checkedNodes = checkedNodes;
setOutputMarkupId(true);
}
@Override
protected IModel<Boolean> newCheckBoxModel(IModel<T> model) {
checkboxModel = new CheckModel();
return checkboxModel;
}
@Override
protected void onUpdate(AjaxRequestTarget target) {
super.onUpdate(target);
T node = getModelObject();
boolean nodeChecked = checkboxModel.getObject();
addRemoveSubNodes(node, nodeChecked);
addRemoveAncestorNodes(node, nodeChecked);
updateNodeOnClientSide(target, nodeChecked);
}
protected void updateNodeOnClientSide(AjaxRequestTarget target,
boolean nodeChecked) {
target.appendJavaScript(";CheckAncestorsAndChildren.checkChildren('" + getMarkupId() + "',"
+ nodeChecked + ");");
target.appendJavaScript(";CheckAncestorsAndChildren.checkAncestors('" + getMarkupId() + "',"
+ nodeChecked + ");");
}
@Override
public void renderHead(IHeaderResponse response) {
PackageResourceReference scriptFile = new PackageResourceReference(this.getClass(), "autocheckedFolder.js");
response.render(JavaScriptHeaderItem.forReference(scriptFile));
}
protected void addRemoveSubNodes(T node, Boolean nodeStatus) {
Iterator<? extends T> childrenNodes = treeProvider.getChildren(node);
while (childrenNodes.hasNext()) {
T childNode = childrenNodes.next();
addRemoveSubNodes(childNode, nodeStatus);
}
if(nodeStatus)
checkedNodes.getObject().add(node);
else
checkedNodes.getObject().remove(node);
}
protected void addRemoveAncestorNodes(T node, Boolean nodeStatus) {
BranchItem currentConatiner = findParent(BranchItem.class);
if(currentConatiner == null) {
return;
}
BranchItem ancestor = currentConatiner.findParent(BranchItem.class);
while(ancestor != null)
{
T nodeObject = (T) ancestor.getDefaultModelObject();
if(nodeStatus)
{
checkedNodes.getObject().add(nodeObject);
}
else
{
if(!hasNodeCheckedChildren(nodeObject))
checkedNodes.getObject().remove(nodeObject);
}
ancestor = ancestor.findParent(BranchItem.class);
}
}
protected boolean hasNodeCheckedChildren(T nodeObject) {
Iterator<? extends T> children = treeProvider.getChildren(nodeObject);
while (children.hasNext()) {
T child = children.next();
if(checkedNodes.getObject().contains(child))
return true;
}
return false;
}
class CheckModel extends AbstractCheckBoxModel {
@Override
public void detach() {
}
@Override
public boolean isSelected() {
return checkedNodes.getObject()
.contains(getModelObject());
}
@Override
public void select() {
checkedNodes.getObject().add(getModelObject());
}
@Override
public void unselect() {
checkedNodes.getObject().remove(getModelObject());
}
}
}
自然的是applicaiton
public class WicketApplication extends WebApplication {
@Override
public Class<? extends Page> getHomePage() {
return HomePage.class;
}
}
来看一下web.xml文件
<web-app>
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>wicket.AnnotationsRolesStrategyExample</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>demo.WicketApplication</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>wicket.AnnotationsRolesStrategyExample</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>