xilong008

spark组织架构开发经验(客户端插件)

参考了两篇文章,终于搞定了客户端插件,但服务器端插件开发没有参考资料,有经验的朋友请联系交流。

参考资料为:http://hi.baidu.com/awol2005ex/item/8c673626e8ff493194f62bd0

http://www.cnblogs.com/openfire/archive/2013/04/26/3044722.html

这两篇文章中都有小问题,要细心才能发现,两个方法都能生成插件。

这里需要json   jar包,csdn有下

导入lib就行。

/spark/src/plugins/orgtree目录下的结构为

代码放在com.salesoa.orgtree包内

下面送上各个类的代码:

OrgTree.java

package com.salesoa.orgtree;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingWorker;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.tree.DefaultTreeCellRenderer;
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.JiveTreeNode;
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();
    }
 
    
}

OrgTreeCellRenderer.java

package com.salesoa.orgtree;

import java.awt.Component;
import java.awt.Font;

import javax.swing.Icon;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;

import org.jivesoftware.spark.component.JiveTreeNode;

//机构节点
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();
    }

}

OrgTreeNode.java

package com.salesoa.orgtree;

import org.jivesoftware.spark.component.JiveTreeNode;

//机构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;
}


}

OrgTreePlugin.java

package com.salesoa.orgtree;

import java.net.URL;

import javax.swing.ImageIcon;

import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.Workspace;
import org.jivesoftware.spark.component.tabbedPane.SparkTabbedPane;
import org.jivesoftware.spark.plugin.Plugin;

//展示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=new OrgTree();//机构树

        
        
        // 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

    }

}

build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="OrgTreePlugin" default="release" basedir="..">
 <property name="src.dir" value="src" />
 <property name="dest.dir" value="bin" />
 <property name="lib.dir" value="lib" />
 <property name="im.path" value="lib/dist" />


 <property name="spark.home" value="../../../target/build/lib" />


 <path id="lib.classpath">
  <fileset dir="${spark.home}" includes="**/*.jar, **/*.zip" />
 </path>

 <target name="clean">
  <delete dir="${dest.dir}" />
  <delete dir="${lib.dir}" />
  <delete dir="${im.path}" />
 </target>

 <target name="init" depends="clean">
  <mkdir dir="${dest.dir}" />
  <mkdir dir="${lib.dir}" />
  <mkdir dir="${im.path}" />
 </target>

 <target name="build" depends="init">
  <javac srcdir="${src.dir}" destdir="${dest.dir}" classpathref="lib.classpath" target="1.6" />
 </target>

 <!-- 最重要的是这里,打两次包 -->
 <target name="jar" depends="build">
  <jar jarfile="${lib.dir}/OrgTreePlugin.jar" basedir="${dest.dir}" />
  <jar jarfile="${im.path}/OrgTreePlugin.jar">
   <fileset dir=".">
    <include name="lib/*.jar" />
   </fileset>
   <fileset dir=".">
    <include name="plugin.xml" />
   </fileset>
  </jar>
 </target>
 <target name="release" depends="jar">
 
 </target>
</project>

plugin.xml

<!-- Define your plugin -->
<plugin>
    <name>Organizational Plugin</name>
    <version>1.0</version>
    <author>HuiLong</author>
    <homePage></homePage>
    <email>HuiLong@chengrui.cc</email>
    <description></description>
    <class>com.salesoa.orgtree.OrgTreePlugin</class>
    <minSparkVersion>1.6.0</minSparkVersion>
</plugin>

以上全部整理完毕后,打开ant窗口,编译build.xml就可以得到插件jar包。

 

分类:

技术点:

相关文章: