1.把五级联表通过树的形式显示在界面上
1.该显示通过2中方式,一种是显示所有的五级数据(耗时很大)
2.显示需要的数据,但是每次点击显示子集的时候有数据延迟.
备注:改代码用于实现别的功能的,部分冗余,不影响正常显示实现.
MainDemo类
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
public class MainDemo implements ActionListener{
public JButton localJB,searchJB,showIpJB,reFreshJB,searchFileJB,villageJB,allVillageJB;
public JTextField ipText,fileNameText;
public JComboBox jcomboBox;
public JLabel fileJL;//用于统计文件个数
public JPanel mainTreeJP;
public static void main(String[] args) {
MainDemo mainDemo=new MainDemo();
mainDemo.init();//初始化界面
}
public void init(){
JFrame jframe=new JFrame();
jframe.setSize(1200,1000);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setTitle("文件检索");
jframe.setLayout(new BorderLayout());
//操作面板
JPanel opearJP=new JPanel(new BorderLayout());
opearJP.setBorder(BorderFactory.createTitledBorder("操作"));
opearJP.setPreferredSize(new Dimension(1200,100));
jframe.add(opearJP,BorderLayout.NORTH);
JPanel leftOpearJP=new JPanel(new FlowLayout(FlowLayout.LEFT));
leftOpearJP.setPreferredSize(new Dimension(600,100));
opearJP.add(leftOpearJP,BorderLayout.WEST);
localJB=new JButton("本机文件显示");
leftOpearJP.add(localJB);
leftOpearJP.add(new JLabel("请输入服务器IP地址"));
ipText=new JTextField("", 15);
leftOpearJP.add(ipText);
searchJB=new JButton("扫描该机器");
leftOpearJP.add(searchJB);
showIpJB=new JButton("显示该IP机器文件");
leftOpearJP.add(showIpJB);
//村落树显示
villageJB=new JButton("村落树显示");
leftOpearJP.add(villageJB);
//显示所有的村落树
allVillageJB=new JButton("显示所有的村落树");
leftOpearJP.add(allVillageJB);
localJB.addActionListener(this);
searchJB.addActionListener(this);
showIpJB.addActionListener(this);
villageJB.addActionListener(this);
allVillageJB.addActionListener(this);
//用于显示文件目录
JPanel rightOpearJP=new JPanel(new FlowLayout(FlowLayout.LEFT));
rightOpearJP.setPreferredSize(new Dimension(550,100));
opearJP.add(rightOpearJP,BorderLayout.EAST);
reFreshJB=new JButton("统计类目文件");
rightOpearJP.add(reFreshJB);
jcomboBox=new JComboBox();
jcomboBox.setPreferredSize(new Dimension(150,28));
rightOpearJP.add(jcomboBox);
rightOpearJP.add(new JLabel("该类目下的文件个数:"));
fileJL=new JLabel(" ");
rightOpearJP.add(fileJL);
rightOpearJP.add(new JLabel("请输入文件名:"));
fileNameText=new JTextField("",20);
rightOpearJP.add(fileNameText);
searchFileJB=new JButton("文件搜索");
rightOpearJP.add(searchFileJB);
reFreshJB.addActionListener(this);
searchFileJB.addActionListener(this);
//显示面板
JPanel showJP=new JPanel(new BorderLayout());
showJP.setBorder(BorderFactory.createTitledBorder("显示"));
showJP.setPreferredSize(new Dimension(1200,900));
jframe.add(showJP,BorderLayout.CENTER);
//树结构显示
JPanel showTree=new JPanel(new BorderLayout());
showTree.setPreferredSize(new Dimension(600,900));
showJP.add(showTree,BorderLayout.WEST);
mainTreeJP=new JPanel(new GridLayout(0,1));//用于存放所有显示的树
JScrollPane leftJSP=new JScrollPane(mainTreeJP,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED );
showTree.add(leftJSP,BorderLayout.CENTER);
//文件显示
JPanel showFile=new JPanel(new BorderLayout());
showFile.setPreferredSize(new Dimension(600,900));
showJP.add(showFile,BorderLayout.EAST);
jframe.setVisible(true);
}
//按钮监听事件localJB,searchJB,showIpJB;reFreshJB,searchFileJB
public void actionPerformed(ActionEvent e){
if(localJB==e.getSource()){
System.out.println("本地文件扫描");
JPanel localTreeJP=new JTreeDemo().getLocalTree();
mainTreeJP.add(localTreeJP);
System.out.println("文件扫描完毕,可以显示");
}else if(searchJB==e.getSource()){
System.out.println("扫描"+ipText.getText()+"的文件");
}else if(showIpJB==e.getSource()){
System.out.println("显示"+ipText.getText()+"的文件");
}else if(reFreshJB==e.getSource()){
System.out.println("统计类目文件");
}else if(searchFileJB==e.getSource()){
System.out.println("搜索文件");
}else if(villageJB==e.getSource()){
//村落树显示方式,
//1,把所有的都显示出来(找到最大极限);
//2.显示需要看到的树即可
System.out.println("村落树显示");
JPanel villageJP=new JTreeDemo().getVillageTree();
mainTreeJP.add(villageJP);
System.out.println("村落树显示完毕");
}else if(allVillageJB==e.getSource()){
System.out.println("显示所有的村落树");
JPanel allVillageJP=new JTreeDemo().getallVillageTree();
mainTreeJP.add(allVillageJP);
System.out.println("显示所有的村落树完成");
}
}
}
JTreeDemo类
import java.io.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.util.concurrent.*;
import java.sql.*;
public class JTreeDemo
{
//返回本地文件树
public JPanel getLocalTree(){
JPanel panel=new JPanel(new BorderLayout());
DefaultMutableTreeNode root=new DefaultMutableTreeNode("本机电脑");
//返回本机所有磁盘名称
String[] rootsName=getRootsName();
for(String str:rootsName){
DefaultMutableTreeNode node=new DefaultMutableTreeNode(str);
root.add(node);
}
int size=rootsName.length;
//创建线程,为每一个磁盘创建一个线程,然后进行扫描
CountDownLatch latch=new CountDownLatch(1);///主线程
CountDownLatch Sublatch=new CountDownLatch(2);
ExecutorService exec=Executors.newFixedThreadPool(size);
for(int i=0;i<size;i++){
Thread t=new Thread(new ThreadDemo(rootsName[i]));
t.start();
}
latch.countDown();
try{
Sublatch.await();
}catch(InterruptedException e){
System.out.println("主线程运行出错");
e.printStackTrace();
}
System.out.println("搜索完毕,可以显示");
JTree tree=new JTree(root);
panel.add(tree);
panel.add(new JLabel("本机文件"),BorderLayout.NORTH);
return panel;
}
//返回本机所有磁盘的名称
public String[] getRootsName(){
File[] rootsFile=File.listRoots();
String rootsName[]=new String[rootsFile.length];
for(int i=0;i<rootsName.length;i++){
rootsName[i]=rootsFile[i].getAbsolutePath();
}
return rootsName;
}
//返回村落树
public JPanel getVillageTree(){
//连接一次数据库即可
Connection conn=new SqlDemo().getConnection();
JPanel panel=new JPanel(new BorderLayout());
String startStr="中国";
DefaultMutableTreeNode root=new DefaultMutableTreeNode(startStr);
//为树添加监听事件
JTree tree=new JTree(root);
panel.add(tree);
panel.add(new JLabel("村落树"),BorderLayout.NORTH);
tree.addTreeSelectionListener(new TreeSelectionListener(){
public void valueChanged(TreeSelectionEvent e){
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
System.out.println("点击了:"+node.toString());
String startIdName=node.toString();
//把子类加入到给node里面
new SqlDemo().addChildNode(node, startIdName,conn);
System.out.println("显示完毕");
}
});
return panel;
}
//用于显示所有的村落树
public JPanel getallVillageTree(){
Connection conn=new SqlDemo().getConnection();
JPanel panel=new JPanel(new BorderLayout());
String startStr="屯溪区";
//计时开始
long startTime = System.currentTimeMillis();
DefaultMutableTreeNode root=new DefaultMutableTreeNode(startStr);
//获得所有的子集
new SqlDemo().getAllChild(root,conn);
//为树添加监听事件
JTree tree=new JTree(root);
panel.add(tree);
panel.add(new JLabel("村落树"),BorderLayout.NORTH);
//计时结束
long endTime=System.currentTimeMillis();
System.out.println("显示"+startStr+"树耗时"+(endTime-startTime)/1000+"秒");
return panel;
}
}
SqlDemo类
import java.sql.*;
import javax.swing.tree.DefaultMutableTreeNode;
public class SqlDemo{
private static String root="rootes";
private static String password="123456";
private static String name="com.mysql.jdbc.Driver";
private static String url="jdbc:mysql://192.168.65.99/village";
private static Connection conns=null;
//private static Statement stat=null;
private static PreparedStatement prstat=null;
//连接数据库
public static Connection getConnection(){
Connection conn=null;
try{
Class.forName(name);
conn=DriverManager.getConnection(url,root,password);
System.out.println("数据库连接成功");
}catch(Exception e){
System.out.println("连接数据库失败");
e.printStackTrace();
}
return conn;
}
//把子类的所有node加入进入
public void addChildNode(DefaultMutableTreeNode nodes,String parentName,Connection conn){
try{
//conn=getConnection();
Statement stat=conn.createStatement();
String sqlName="select city_code from tb_region where name='"+parentName+"'";
ResultSet rsName=stat.executeQuery(sqlName);
String codeId="";
while(rsName.next()){
codeId=rsName.getString("city_code");
}
String sqlId="select name from tb_region where parent_code='"+codeId+"'";
ResultSet rsID=stat.executeQuery(sqlId);
if(rsID.next()){
rsID.previous();//如果存在就向上移动一格.
while(rsID.next()){
System.out.println("子类结果:"+rsID.getString("name"));
DefaultMutableTreeNode node=new DefaultMutableTreeNode(rsID.getString("name"));
nodes.add(node);
}
}else{
System.out.println("没有子集了");
}
}catch(SQLException e){
System.out.println("查询异常");
e.printStackTrace();
}/*finally{
try{
//rsName.close();
//rsID.close();
stat.close();
conn.close();
System.out.println("查询完成");
}catch(SQLException e){
System.out.println("关闭数据失败");
e.printStackTrace();
}
}*/
}
//获取所有的子集元素,深度优先遍历
public void getAllChild(DefaultMutableTreeNode root,Connection conn){
try{
String parentName=root.toString();
Statement stat=conn.createStatement();
String sqlName="select city_code from tb_region where name='"+parentName+"'";
ResultSet rsName=stat.executeQuery(sqlName);
String codeId="";
while(rsName.next()){
codeId=rsName.getString("city_code");
}
String sqlId="select * from tb_region where parent_code='"+codeId+"'";
ResultSet rsID=stat.executeQuery(sqlId);
while(rsID.next()){
DefaultMutableTreeNode node=new DefaultMutableTreeNode(rsID.getString("name"));
int level_type=rsID.getInt("level_type");
if(level_type==3){
System.out.println("当前城市级别:"+node.toString());
}
//System.out.println(node.toString());
if(level_type!=5){
root.add(node);
getAllChild(node,conn);
}else{
root.add(node);
}
}
}catch(Exception e){
System.out.println("查询异常");
e.printStackTrace();
}
}
}
部分功能是冗余的,与该联表无关,可以自行删减备注掉(冗余的实现其他类也不提供了)
运行结果截图提供
点击这2个可以实现对应功能
点击后缩放一些面板,因为没有进行刷新,手动缩放面板即可刷新
村落树显示:点击显示可见的下级
显示所有的村落树:更新条件显示所有的子集,(等级越大显示越多,耗时越多,测试了显示一个区的所有子集耗时70多秒)
对于树会不会出现一下子显示70多万条数据出问题,本机测试了,树上过多少都行,到1千万条的时候就溢出了.
显示结果:
提供了五级联表的数据库(内部包含了3个类型的数据库)每个都有70多万条记录,一般都可以实现,
需要了五级联表的数据库可以点击链接获取:https://download.csdn.net/download/hongfei568718926/11982263
我选用并删减了部分列,同时加入了一条为中国的记录,标的结构如下图所示