项目里有这样一个需求:要查看系统文件夹里面的所有图片,按目录分门别类放置。
其实说白了就是做一个树状的列表
如下图
工作过几年的程序员,应该知道,一旦碰上类似的问题,就先去网上找找,看有没有现有的组件能帮助我们,别一个人在电脑前傻兮兮的自己想。很多问题,我们并不是第一个遇到的,肯定有前辈为我们找到了合适的方法。如果实在找不到组件,那再自己写。即使找不到,但是至少,你得先去找过!
一个优秀的程序员应该学会参考别人的代码。
OK先介绍一个这个组件
全名 JSTree
官网 https://www.jstree.com/
git https://github.com/vakata/jstree
说明文档也在git上
我先来简单介绍一下这个组件吧
下面这个例子的代码如下:
就上面的代码来说,组件第一次给后台发的请求是www.jstree.com/fiddle/?lazy&id=#
返回的json如下:
你点击一下这个item,组件就会再次向后台请求新的数据,请求地址是www.jstree.com/fiddle/?lazy&id=2
返回的结果是
["Child node 3","Child node 4"]
我们看到的是
OK我们看后台处理逻辑
<Connector connectionTimeout="20000" port="8700" URIEncoding="utf-8" protocol="HTTP/1.1" redirectPort="8443"/>
加上 URIEncoding="utf-8"后,在代码里就不需要转换了。
下面就是读取某个文件下的文件夹和文件了。
那么怎么做的我点击列表里的图片,在右边就显示它呢?
这说白了就是jstree的事件功能么。
其实我们刚才说了item有个children属性如果是true就说明是文件夹,反之就是文件
可是我在事件里找不到那个children属性..惭愧...
api如下:大家看看
其实说白了就是做一个树状的列表
如下图
而我电脑上的文件组织就和显示的一样:
工作过几年的程序员,应该知道,一旦碰上类似的问题,就先去网上找找,看有没有现有的组件能帮助我们,别一个人在电脑前傻兮兮的自己想。很多问题,我们并不是第一个遇到的,肯定有前辈为我们找到了合适的方法。如果实在找不到组件,那再自己写。即使找不到,但是至少,你得先去找过!
一个优秀的程序员应该学会参考别人的代码。
OK先介绍一个这个组件
全名 JSTree
官网 https://www.jstree.com/
git https://github.com/vakata/jstree
说明文档也在git上
我先来简单介绍一下这个组件吧
下面这个例子的代码如下:
<div id="container"></div>
<script>
$(function() {
$('#container').jstree({
'core' : {
'data' : {
"url" : "//www.jstree.com/fiddle/?lazy",
"data" : function (node) {
return { "id" : node.id };
}
}
}
});
});
</script>
就上面的代码来说,组件第一次给后台发的请求是www.jstree.com/fiddle/?lazy&id=#
返回的json如下:
[{
"id":1,"text":"Root node","children":[
{"id":2,"text":"Child node 1","children":true},
{"id":3,"text":"Child node 2"}
]
}]
看到了吧,id为2的item的children属性是true,这说明什么?说明这个item下面还有文件/文件夹
你点击一下这个item,组件就会再次向后台请求新的数据,请求地址是www.jstree.com/fiddle/?lazy&id=2
返回的结果是
["Child node 3","Child node 4"]
我们看到的是
OK,现在上我写的例子:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>标题</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script src="js/jquery.min.js"></script>
<script src="js/jstree.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<link rel="stylesheet" href="css/style.min.css" />
<link rel="stylesheet" href="css/bootstrap.min.css" />
</head>
<body>
<div id="container" style="float:left;margin-left: 15%;margin-top: 0.51%;"></div>
<div id="pic" style="padding-left: 80px; padding-top: 80px;" >
<img id="plant" alt="" src="" style="padding-left: 10%;" >
</div>
</body>
<script type="text/javascript">
$(function() {
$('#container').jstree({
'core' : {
'data' : {
"url" : "http://localhost:8700/ShowPictures/ShowIndex",
"data" : function (node) {
return { "id" : node.id };
}
}
}
});
$('#container').on("changed.jstree", function (e, data) {
var name=String(data.selected); //必须得转换成字符串
// alert(name);
if(name.search("jpg")>1||name.search("png")>1){
$("#plant").attr("src",name);
// $("#pic").hide();
}
});
});
</script>
</html>
OK我们看后台处理逻辑
@WebServlet( urlPatterns = "/ShowIndex")
public class ShowIndexServlet extends HttpServlet {
/**
* https://github.com/vakata/jstree
*/
private static final long serialVersionUID = -3867365983209162571L;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
String result="";
String id=request.getParameter("id");
// System.out.println("i get id "+id);
// public static final String PLANT_LOCATION="E:\\plant";
// public static final String PARENT_LOCATION="E:\\";
if (id.equals("#")) {
result=ShowFiles.getChildrenFiles(Config.PLANT_LOCATION);
}else{
// id = new String (id.getBytes("iso-8859-1"), "UTF-8") ;
result=ShowFiles.getChildrenFiles(Config.PARENT_LOCATION+id);
}
out.write(result);
out.flush();
out.close();
}
}
注意:因为我的目录上有中文,本来是使用id = new String (id.getBytes("iso-8859-1"), "UTF-8") ; 来做转换的,后来发现tomcat路径中文问题直接在server.xml的Connector里加上 URIEncoding="utf-8"即可:
<Connector connectionTimeout="20000" port="8700" URIEncoding="utf-8" protocol="HTTP/1.1" redirectPort="8443"/>
加上 URIEncoding="utf-8"后,在代码里就不需要转换了。
下面就是读取某个文件下的文件夹和文件了。
public class ShowFiles {
public static String getChildrenFiles(String parentPath) {
JSONArray list = new JSONArray();
File file = new File(parentPath);
File[] tempList = file.listFiles();
// System.out.println("该目录下对象个数:" + tempList.length);
String fileName="";
for (int i = 0; i < tempList.length; i++) {
JSONObject item = new JSONObject();
if (tempList[i].isFile()) {
// System.out.println("文 件:" + tempList[i]);
//为什么substring(3) 因为我去掉了盘符
item.put("id", tempList[i].toString().substring(3));
//每一个item都有哪些属性?自己去git上看吧
item.put("icon", "images/icon.png");
fileName=tempList[i].getName();
item.put("text", fileName.substring(0,fileName.lastIndexOf(".")));
}
if (tempList[i].isDirectory()) {
// System.out.println("文 件夹:" + tempList[i]);
item.put("id", tempList[i].toString().substring(3));
item.put("text", tempList[i].getName());
//如果是文件夹 children就是true
item.put("children", true);
}
list.add(item);
}
// System.out.println(list);
return list.toString();
}
}
看到上面的代码,大家应该明白了,列表里每个item的id就是这个文件/文件夹的全地址(我去掉了盘符),text(就是在页面上显示的内容)是文件名
那么怎么做的我点击列表里的图片,在右边就显示它呢?
这说白了就是jstree的事件功能么。
//点击任何一个item就会调用下面的的代码
$('#container').on("changed.jstree", function (e, data) {
var name=String(data.selected); //必须得转换成字符串
// alert(name);
if(name.search("jpg")>1||name.search("png")>1){
$("#plant").attr("src",name);
}
});
});
如果item的id里面包含了jpg或者png我就认为它是图片
其实我们刚才说了item有个children属性如果是true就说明是文件夹,反之就是文件
可是我在事件里找不到那个children属性..惭愧...
api如下:大家看看
项目使用的js/与css如下:
http://pan.baidu.com/s/1jIqaJLc