openfire + spark 展示组织机构(客户端)
在spark 加一个插件用于展示组织机构, 参考了好多人的代码
插件主类增加一个 TAB用于展示机构树
package com.salesoa.orgtree;
import java.net.URL; //展示OA的组织结构
public class OrgTreePlugin implements Plugin{ private static ImageIcon organ_icon=null; public static ImageIcon getOrganIcon(){//机构图标
if(organ_icon==null){
ClassLoader cl=OrgTreePlugin.class.getClassLoader();
URL imageURL=cl.getResource("images/organ.gif");
organ_icon=new ImageIcon(imageURL);
}
return organ_icon;
} private static ImageIcon user_icon=null; public static ImageIcon getUserIcon(){//机构图标
if(user_icon==null){
ClassLoader cl=OrgTreePlugin.class.getClassLoader();
URL imageURL=cl.getResource("images/user.gif");
user_icon=new ImageIcon(imageURL);
}
return user_icon;
} @Override
public void initialize() {
// TODO Auto-generated method stub
Workspace workspace=SparkManager.getWorkspace(); SparkTabbedPane tabbedPane=workspace.getWorkspacePane(); OrgTree orgTreePanel=newOrgTree();//机构树 // Add own Tab.
tabbedPane.addTab("组织架构",OrgTreePlugin.getOrganIcon(),orgTreePanel);
} @Override
public void shutdown() {
// TODO Auto-generated method stub } // 是否可关闭
@Override
public boolean canShutDown() {
// TODO Auto-generated method stub
return false;
} // 卸载
@Override
public void uninstall() {
// TODO Auto-generated method stub } }
机构树类 ,根据openfire插件http过来数据展示
package com.salesoa.orgtree; import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.IOException; import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingWorker;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.tree.DefaultTreeModel; import net.sf.json.JSONArray;
import net.sf.json.JSONObject; import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.component.Tree;
import org.jivesoftware.spark.util.log.Log; //组织机构树
public class OrgTree extends JPanel {
/**
*
*/
private static final long serialVersionUID = 5238403584089521528L; private final Tree orgTree;// 机构树控件
private final OrgTreeNode rootNode = new OrgTreeNode("组织");// 根节点
private final DefaultTreeModel treeModel;// 树模型 // 初始化机构树
public OrgTree() { // 根节点
rootNode.setUnitid(null);
rootNode.setSuperunitid1(null);
rootNode.setVisited(false);
rootNode.setAllowsChildren(true);// 允许有子节点
rootNode.setIcon(OrgTreePlugin.getOrganIcon());// 图标 // 机构树
orgTree = new Tree(rootNode);
orgTree.setShowsRootHandles(true); // 显示根结点左边的控制手柄
orgTree.collapseRow(0); // 初始时只显示根结点
orgTree.setCellRenderer(new OrgTreeCellRenderer());
// 覆盖树展开事件,进行异步加载
orgTree.addTreeExpansionListener(new TreeExpansionListener() {
@Override
public void treeExpanded(TreeExpansionEvent event) {
// 首先获取展开的结点
final OrgTreeNode expandNode = (OrgTreeNode) event.getPath()
.getLastPathComponent(); // 判断该节点是否已经被访问过
// 是——无需到数据库中读取、什么事也不做
// 否——开始异步加载
if (!expandNode.getVisited()) {
expandNode.setVisited(true); // 先改变visited字段的状态
orgTree.setEnabled(false); // 暂时禁用JTree // 使用swingworker框架
new SwingWorker<Long, Void>() {
@Override
protected Long doInBackground() throws Exception {
return asynchLoad(expandNode);
} @Override
protected void done() {
treeModel.removeNodeFromParent(expandNode
.getFirstLeaf()); // 加载完毕后要删除“载入中...”结点
treeModel.nodeStructureChanged(expandNode); // 通知视图结构改变 orgTree.setEnabled(true);//重新启用JTree
}
}.execute(); }
} @Override
public void treeCollapsed(TreeExpansionEvent event) {
}
}); treeModel = (DefaultTreeModel) orgTree.getModel();// 树模型 //排版
setLayout(new BorderLayout()); final JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.setBackground(Color.white); final JScrollPane treeScroller = new JScrollPane(orgTree);// 滚动条
treeScroller.setBorder(BorderFactory.createEmptyBorder());
panel.add(treeScroller, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,
GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(5,
5, 5, 5), 0, 0));// 设置边界 add(panel, BorderLayout.CENTER); rootNode.add(new OrgTreeNode("加载中..."));// 用于显示正在加载
} // 从数据表中读取expandNode的子结点.返回值为处理时长
private long asynchLoad(OrgTreeNode expandNode) {
long handleTime = 0L; // 本次异步加载的处理时长
long start = System.currentTimeMillis(); // 开始处理的时刻
try {
Thread.sleep(1000); // sleep一段时间以便看清楚整个过程 JSONArray childJSON = this.getOrgTreeJSON(expandNode.getUnitid());
if (childJSON != null && childJSON.size() > 0) { for (int i = 0, s = childJSON.size(); i < s; i++) {
JSONObject u = childJSON.getJSONObject(i);
OrgTreeNode node = new OrgTreeNode(u.getString("unitname"));
node.setUnitid(u.getString("unitid"));
if (u.containsKey("superunitid1")) {
node.setSuperunitid1(u.getString("superunitid1"));
}
node.setType(u.getString("type"));
if ("unit".equals(node.getType())) {
node.setAllowsChildren(true);// 机构
} else if ("staff".equals(node.getType())) {
node.setAllowsChildren(false);// 人员
if (u.containsKey("loginid")) {
node.setLoginid(u.getString("loginid"));// 登陆账号
}
} node.setVisited(false);
node.setAllowsChildren(true);// 允许有子节点
if ("unit".equals(node.getType())) {// 机构
node.setIcon(OrgTreePlugin.getOrganIcon());// 图标
} else if ("staff".equals(node.getType())) {// 人员
node.setIcon(OrgTreePlugin.getUserIcon());// 图标
}
expandNode.add(node);
if ("unit".equals(node.getType())) {
node.add(new OrgTreeNode("加载中..."));// 用于显示正在加载
}
}
} } catch (Exception ex) {
Log.error("", ex);
} finally {
handleTime = System.currentTimeMillis() - start; // 计算出处理时长
}
return handleTime; } private JSONArray getOrgTreeJSON(String unitid) {// 取得返回组织架构
JSONArray result = new JSONArray();
HttpClient httpClient = new HttpClient();
GetMethod getMethod = new GetMethod(this.getOrgUrl(unitid));
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler());
try {
httpClient.executeMethod(getMethod); byte[] responseBody = getMethod.getResponseBody();
String responseMsg = new String(responseBody, "GBK");
result = JSONArray.fromObject(responseMsg);
} catch (HttpException e) {
// TODO Auto-generated catch block
Log.error("", e);
} catch (IOException e) {
// TODO Auto-generated catch block
Log.error("", e);
} finally { getMethod.releaseConnection();
} return result;
} private String getOrgUrl(String unitid) {// 取得返回组织架构的url
String host = SparkManager.getConnection().getHost();
StringBuffer url = new StringBuffer("http://");
url.append(host);
url.append(":9090/plugins/orgtree/orgtreeservlet");
if (unitid != null) {
url.append("?unitid=");
url.append(unitid);
}
return url.toString();
}
}
有时间继续研究与联系人 ,对话之类结合的问题
-----------------------补充
//机构节点
public class OrgTreeCellRenderer extends DefaultTreeCellRenderer { /**
*
*/
private static final long serialVersionUID = 1759820655239259659L;
private Object value; /**
* Empty Constructor.
*/
public OrgTreeCellRenderer() {
} public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
this.value = value; final Component c = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); //设置图标
setIcon(getCustomIcon()); //用中文字体解决乱码问题
// Root Nodes are always bold
JiveTreeNode node = (JiveTreeNode)value;
if (node.getAllowsChildren()) {
setFont(new Font("宋体", Font.BOLD, 13));
}
else {
setFont(new Font("宋体", Font.PLAIN, 13));
} return c;
} //取得图标
private Icon getCustomIcon() {
if (value instanceof JiveTreeNode) {
JiveTreeNode node = (JiveTreeNode)value;
return node.getClosedIcon();
}
return null;
} //关闭的图标
public Icon getClosedIcon() {
return getCustomIcon();
} public Icon getDefaultClosedIcon() {
return getCustomIcon();
} //叶子的图标
public Icon getDefaultLeafIcon() {
return getCustomIcon();
} public Icon getDefaultOpenIcon() {
return getCustomIcon();
} public Icon getLeafIcon() {
return getCustomIcon();
} //打开的图标
public Icon getOpenIcon() {
return getCustomIcon();
} } //机构Node
public class OrgTreeNode extends JiveTreeNode implements java.io.Serializable{ public OrgTreeNode(String unitname) {
super(unitname);
} /**
*
*/
private static final long serialVersionUID = -5358854185627562145L;
private String unitid ;//机构ID
private String unitname ; //机构名称
private String superunitid1; //上一级机构名称
private Boolean visited;//是否已访问
private String type; //类型
private String loginid;//登陆账号
public String getUnitid() {
return unitid;
} public void setUnitid(String unitid) {
this.unitid = unitid;
} public String getUnitname() {
return unitname;
} public void setUnitname(String unitname) {
this.unitname = unitname;
} public String getSuperunitid1() {
return superunitid1;
} public void setSuperunitid1(String superunitid1) {
this.superunitid1 = superunitid1;
} public Boolean getVisited() {
return visited;
} public void setVisited(Boolean visited) {
this.visited = visited;
} public String getType() {
return type;
} public void setType(String type) {
this.type = type;
} public String getLoginid() {
return loginid;
} public void setLoginid(String loginid) {
this.loginid = loginid;
} }
openfire + spark 展示组织机构(客户端)的更多相关文章
- openfire spark 二次 开发 服务插件
==================== 废话 begin ============================ 最近老大让我为研发平台增加即时通讯功能.告诉我用comet 在web端实现即 ...
- 即时通讯软件openfire+spark+smack
所以我基本上分为三篇文章来介绍此类软件的开发: 第一篇是关于XMPP 协议是啥,IM 是啥以及一个比较有名的开源实现,该开源实现包括三个部分(Spark.Smack和Openfire): 第二篇讲如何 ...
- openfire/spark/asmack 环境调试纪要
项目需要简单搭建openfire/spark/asmack的环境及程序demo,本文简单记录以免遗忘. 1.openfire/spark 是java编写的xmpp服务器及PC客户端,安装过程相当简单一 ...
- openfire+spark+smack实现即时通讯
近公司项目需要用到即时通讯功能,经过调研发现openfire+spark+smack可以实现.在网上找了很久,资料都十分有限,即使有些朋友实现了也说的不清不楚.于是决定自己研究,耗时一周的时间实现了文 ...
- iOS xmpp Openfire+spark环境搭建
配置这个遇到太多问题了,写下来分享 首先到官网下载openfire+spark 下载地址:http://www.igniterealtime.org/downloads/index.jsp
- 技术笔记:XMPP之openfire+spark+smack
在即时通信这个领域目前只找到一个XMPP协议,在其协议基础上还是有许多成熟的产品,而且是开源的.所以还是想在这个领域多多了解一下. XMPP协议:具体的概念我就不写了,毕竟这东西网上到处是.简单的说就 ...
- Openfire+spark在linux上搭建内部聊天系统
一. 实验环境 Ubuntu server14.04 openfire:http://www.igniterealtime.org/downloads/index.jsp spark:http: ...
- spark-sql(spark sql cli)客户端集成hive
1.安装hadoop集群 参考:http://www.cnblogs.com/wcwen1990/p/6739151.html 2.安装hive 参考:http://www.cnblogs.com/w ...
- Xampp+Openfire+Spark的简单使用
Openfire与Spark的简单实用 1.安装Openfire 百度云 提取码:uu11 2.查找路径 /usr/local/openfire 这时候需要将openfire的文件属性都设置为 可读可 ...
随机推荐
- MEF(Managed Extensibility Framework)有选择性地使用扩展组件
在"MEF(Managed Extensibility Framework)使用全部扩展组件"中,客户端应用程序调用了所有的扩展组件,而且如果有新的扩展组件加入,必须先关闭程序,再 ...
- coco游戏android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := game_shared LOCAL_MODULE_FILENAME ...
- 让Mac风扇面对PD不再疯狂
对于所有喜欢Mac操作系统的用户来说,如果办公环境必须使用Windows及Windows程序,那一定会非常崩溃,因为你很可能使用了Parallels Desktop来运行你的Windows虚拟机,那么 ...
- 不明白的sizeof(enum)数据结构存储问题
不明白的sizeof(enum)数据结构存储问题 typedef struct weekday_st { enum week {sun=123456789,mon,tue,wed,thu,fri,sa ...
- sql的嵌套查询,把一次查询的结果做为表继续进一步查询;内联视图
Mysql的嵌套表查询 嵌套SELECT语句也叫子查询,一个 SELECT 语句的查询结果能够作为另一个语句的输入值.子查询可以: 出现在Where子句中, 出现在from子句中,作为一个临时表使用, ...
- [Linux]在终端启动程序关闭终端不退出的方法
一般情况下关闭终端时,那么在这个终端中启动的后台程序也会终止,要使终端关闭后,后台程序保持执行,使用这个指令: nohup 命令 & 如:nohup test.sh & 回车,然后提示 ...
- Java基础(一):简介
一.java基础语法: 一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作.下面简要介绍下类.对象.方法和实例变量的概念. 对象:对象是类的一个实例,有状态和行为.例如 ...
- JSP简单练习-定时刷新页面
<%@ page contentType="text/html; charset=gb2312" %> <%@ page import="java.ut ...
- Android -- 触摸Area对焦区域(更新)
老早就想找关于不同点击不同地方的对焦,但是一直没有找到,现在项目又需要这个功能,又跑出来找找,最后还是找到啦~~关于对焦更多的是关于自动对焦. 废话不多说,直接来干货,主要是setFocusAreas ...
- python时间格式化及前推
import datetime >>> (datetime.datetime.now() - datetime.timedelta(seconds = 300)).strftime( ...