前段时间为一个朋友做了一个面板之间的交互的功能,我查看了一些技术资料,用Ext2.3实现的,此程序主要用于学习和交流之用,如果涉及到版权的问题,请及时联系我。
例子的功能:west部分展示的是功能模块树,根节点为功能模块 ,它的两个子节点:系统管理和统计报表 ,系统管理有三个子节点:模块管理、角色管理和工号管理。统计报表有2个子节点:员工年收入统计和地区销售额统计。点击功能模块、系统管理和统计报表均不为在center部分打开新的面板,只有点击模块管理、角色管理、工号管理、员工年收入统计和地区销售额统计才会在右边打开新的面板,并在打开新的面板中显示与链接相关的关键信息。
实现的效果图:001.jpg
所使用到的技术:struts2 + JSON + Ext(2.3.0),顺便使用到了Spring。
部分代码的展示:
Strust2的配置文件的部分代码:
<package name="menu" namespace="/menu" extends="struts-default">
<action name="do_*" method="{1}" class="menuAction">
</action>
</package>
MenuAction的代码:
package com.demo.menu.action;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.demo.app.entity.Menu;
import com.demo.common.action.BaseAction;
@SuppressWarnings("serial")
@Scope("prototype")
@Controller("menuAction")
public class MenuAction extends BaseAction {
private List<Menu> menus;
public void getMenus() {
menus = new ArrayList<Menu>();
Menu system = new Menu();
system.setText("系统管理");
system.setCls("folder");
system.setLeaf(false);
system.setId(10); //这里没有设置系统管理的链接值哦!
menus.add(system);
List<Menu> list = new ArrayList<Menu>();
system.setChildren(list);
Menu menu = new Menu();
menu.setText("模块管理");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(11);
menu.setHref("module/do_getList.action");
list.add(menu);
menu = new Menu();
menu.setText("角色管理");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(12);
menu.setHref("role/do_getList.action");
list.add(menu);
menu = new Menu();
menu.setText("工号管理");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(13);
menu.setHref("opertor/do_getList.action");
list.add(menu);
Menu statis = new Menu();
statis.setText("统计报表");
statis.setCls("folder");
statis.setLeaf(false);
statis.setId(20); //这里没有设置统计报表的链接值哦!
menus.add(statis);
list = new ArrayList<Menu>();
statis.setChildren(list);
menu = new Menu();
menu.setText("员工年收入统计");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(21);
menu.setHref("statis/do_statOne.action");
list.add(menu);
menu = new Menu();
menu.setText("地区营业额统计");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(22);
menu.setHref("statis/do_statTwo.action");
list.add(menu);
outJsonArray(menus);
}
}
BaseAction的所用到的部分方法:
public void outJsonArray(Object array) {
JSONArray jsonObject = JSONArray.fromObject(array);
String jsonStr = "";
try {
jsonStr = jsonObject.toString();
} catch (Exception e) {
jsonStr = null;
}
outJsonString(jsonStr);
}
public void outJsonString(String str) {
getResponse().setContentType("text/javascript;charset=UTF-8");
outString(str);
}
public void outString(String str) {
try {
PrintWriter out = getResponse().getWriter();
out.write(str);
} catch (IOException e) {
}
}
以上的代码比较简单,结合例子的功能,看懂应该没有问题。我没有把数据库设计和实现部分的代码写出,也没有给出Menu代码(不过我相信有点基础的人都知道Menu就是一个简单的JavaBean),而是在action中直接生成所需要的数据,起到一个简单模拟的作用。如果觉得有问题,还是回家好好看看java的基础知识吧。
Java部分都讲完了,下面开始结合代码讲解jsp和extjs的使用。
在系统中extjs文件的位置,详见002.jpg
我把jsp和js都放在WebRoot/pages/panel,详见右上图的tmenu01.jsp和tmenu01.js,详细代码如下:
tmenu01.JSP的部分代码:
<%@ page language="java" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":"
+ request.getServerPort() + path + "/";
%>
<link rel="stylesheet" type="text/css" href="<%=basePath%>extjs/css/ext-all.css" />
<script type="text/javascript" src="<%=basePath%>extjs/js/ext-base.js"></script>
<script type="text/javascript" src="<%=basePath%>extjs/js/ext-all-debug.js"></script>
<script type="text/javascript">
Ext.BLANK_IMAGE_URL = '<%=basePath%>/extjs/images/default/s.gif';
//如果不设置的话,west的树形结构有图片找不到
</script>
<script type="text/javascript" src="<%=basePath%>pages/panel/tmenu01.js"></script>
tmenu01.js的全部代码:
var WebApp = {};
WebApp.Desktop = function(){
WestMenu = new Ext.tree.TreePanel({
region : 'west',
margins: '0 5 0 0',
width : 200,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
loader: new Ext.tree.TreeLoader({
dataUrl:'menu/do_getMenus.action'
})
});
var root = new Ext.tree.AsyncTreeNode({
text: '功能模块',
draggable:false,
id:'source'
});
WestMenu.setRootNode(root);
root.expand();
WestMenu.on('click', function(node, e){//设置API树节点的点击监听器 ,这是自己添加的功能
alert("isLeaf="+node.isLeaf()+";text="+node.attributes.text+";node.id="+node.id);
if(node.isLeaf()){//如果是子节点,则进行相应的处理
e.stopEvent();
MainPanel.loadClass(node.attributes.href, node.id,node.attributes.text);
//调用了MainPanel的loadClass的方法(3个参数)
}
});
MainPanel = new Ext.TabPanel({
region : 'center',
activeTab: 0,
items: [{
title : '信息区',
frame : true
}]
});
MainPanel.loadClass = function(href, id, text){
// 给MainPanel添加loadClass的方法(3个参数) ,这是自己添加的功能
var id = id;
var tab = this.getComponent(id);
//根据ID得到一个Component,如果没有对应的Component,
//即tab的值为undefined,说明是第一次被打开.
if(tab){
this.setActiveTab(tab);
}else{
var autoLoad = {url: href};
var p = this.add(new Ext.Panel({
closable: true,
autoScroll:true,
id: id,//id: 'test_panel',//docs-String
cclass : id,//String
title:text+"面板("+id+")",
html:'<h1>面板主区域</h1><br/>'+text+"的URL是"+href,
tbar:[{text:'顶部工具栏topToolbar'}],
bbar:[{text:'底部工具栏bottomToolbar'}],
//autoLoad: autoLoad,//一个对象{url: href}
iconCls: 'icon-cls'
}));
this.setActiveTab(p);
}
};
WebApp.Desktop.superclass.constructor.call(this, {
layout : "border",
items : [ WestMenu, MainPanel]
});
}
Ext.extend(WebApp.Desktop, Ext.Viewport);
//这是EXTJS典型的继承方式,让WebApp.Desktop继承Ext.Viewport