找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 4153|回复: 0

年后第一弹:JAVA类体系图生成器

[复制链接]

307

主题

228

回帖

7343

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5593 个
贡献
253 次
宅之契约
0 份
在线时间
948 小时
注册时间
2014-1-25
发表于 2014-1-31 00:36:05 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
年后第一弹:JAVA类体系图生成器
   
自己DIY的又一JAVA强力工具:类体系关系图

    制作背景:由于是java新手,知道的东西较少,有时候要用到某个功能,而该功能在某个特定类里,而这个类你不一定清楚是什么,该用哪个类一般需要在网上现查,这个工具就是用来快速枚举类的所有派生类超类的,与java的反射机制刚好相反,反射机制让你能找到他的父类或父接口。举个例子:现在要读取文件而且分行读取,假设你只记得一些常识性的东西,例如读取文件要用基于InputStream的类,但是查看InputStream的说明后你会发现该类只能按byte[]读,而分行读这种高级功能一定是派生于InputStream的某个类,但是就是想不起来,因为继承于BufferedReader的有:ByteArrayInputStream    FileInputStream BufferedInputStream DataInputStream 等等很多,真相见图:
lichao.png


但是没有这个工具之前你压根不知道InputStream有这些派生类!只能靠经验,别人写过这个代码,然后你上网去找罢了。这个工具的诞生是我在看到了java反射机制这个强大特性以后突发奇想想到的,目前网上肯定还没有这种东西。不过对我来说初学java理清类还是很重要的,java反射机制其实我只用了低阶的,该工具通过递归查看类信息实现,其实反射还可以动态更改已有类属性和方法,十分强大。
该工具用于查看所有类及接口的继承关系,接口可以看成一种特殊的类,java不支持多重继承也就是只能由一个父类,但是可以继承于多个接口,接口是只有成员函数而无成员变量的类而已,所以在这个角度说,也可以看成java是多重继承的,事实上在程序中我已经这么做了,因为查看父接口也是很重要的,不过这样就导致生成树会有重复部分。这个工具最后做了2分,第一份是包括jdk带的所有运行时库,%JAVA_HOME%\jre\lib 和%JAVA_HOME%\jre\lib\ext 下的所有jar文件解压出来以后不重复的class文件有4W个之多,大家知道一个class对应一个类,现在知道java有多庞大了吧。最后花了20分钟吧所有类解析出来继承关系并生成类树,4M的config.txt是根据这些信息生成的,用于下次启动直接加载不用再次解析,不过由于庞大的数量,完全加载也花了快10分钟。最后由于太多,显然java的JTree出了问题,因为很多都没显示出来了。第二份是rt.jar里的java和javax文件夹,就目前情况而言导入基本上用的都是这里的东西。导入不到半分钟,生成的config.txt有1W行,很快就见到JTree在跳动了。。。如果有第三方库要导入类图,需要解压jar到相应位置,程序启动以后会先从config.txt导入数据,然后遍历指定目录文件加入生成树,每个文件都是一个类,对每个类都要迭代其父类直到父类为null停止,这样就构成了树。对于不支持查看类信息的类生成排除列表。此工具还可在类图形成后进行关键字搜索,搜到的词放到一个JList里,选择后可以直接定位到JTree中,十分方便。          代码只有450行:

  1. package test;

  2. import java.awt.Rectangle;
  3. import java.awt.event.MouseAdapter;
  4. import java.awt.event.MouseEvent;
  5. import java.awt.event.WindowAdapter;
  6. import java.awt.event.WindowEvent;
  7. import java.io.BufferedReader;
  8. import java.io.File;
  9. import java.io.FileInputStream;
  10. import java.io.FileNotFoundException;
  11. import java.io.FileOutputStream;
  12. import java.io.FileReader;
  13. import java.io.PrintStream;
  14. import java.util.LinkedList;
  15. import java.util.Queue;

  16. import javax.swing.DefaultListModel;
  17. import javax.swing.JButton;
  18. import javax.swing.JFrame;
  19. import javax.swing.JLabel;
  20. import javax.swing.JList;
  21. import javax.swing.JScrollPane;
  22. import javax.swing.JTextField;
  23. import javax.swing.JTree;
  24. import javax.swing.event.ListSelectionEvent;
  25. import javax.swing.event.ListSelectionListener;
  26. import javax.swing.tree.DefaultMutableTreeNode;
  27. import javax.swing.tree.DefaultTreeModel;

  28. public class classtree extends JFrame
  29. {
  30.         /**
  31.           *
  32.           */
  33.         private static final long serialVersionUID = 1L;
  34.         private JTextField toSearch=null;
  35.         private JList<String> result=null;
  36.         private JTree tree=null;
  37.         public HashTreeNode root=null;
  38.         public HashTreeNode exception=null;
  39.         private static Queue<String> myqueue=null;
  40.         private String folderpath="C:/Users/Administrator/Desktop/rt";
  41.         private boolean datachanged=false;//增加了文件目录时
  42.         private String tofind=null;
  43.         private LinkedList<Integer> select=null;
  44.         private LinkedList<String> excluded=null;
  45.         JScrollPane scrollPane=null;
  46.         DefaultMutableTreeNode uiroot=null;
  47.        
  48.         public class HashTreeNode
  49.         {
  50.                 public HashTreeNode(String name)
  51.                 {
  52.                         nodename=name;
  53.                         children=new LinkedList<HashTreeNode>();
  54.                 }
  55.                
  56.                 public synchronized HashTreeNode AddChild(String name)
  57.                 {
  58.                         HashTreeNode newnode=null;
  59.                         for(int i=0;i<children.size();i++)
  60.                         {
  61.                                 if(name.equals(children.get(i).nodename))
  62.                                 {
  63.                                         return children.get(i);
  64.                                 }
  65.                                 else if(name.compareTo(children.get(i).nodename) < 0)//name < node
  66.                                 {
  67.                                         newnode=new HashTreeNode(name);
  68.                                         children.add(i,newnode);
  69.                                         return newnode;
  70.                                 }
  71.                         }
  72.                         newnode=new HashTreeNode(name);
  73.                         children.add(newnode);
  74.                         return newnode;
  75.                 }
  76.                
  77.                 public String nodename;
  78.                 public LinkedList<HashTreeNode> children;
  79.         }
  80.        
  81.         public synchronized void AddNodeByString(String[] allpath)
  82.         {
  83.                 HashTreeNode node=root;
  84.                 for(int i=1;i<allpath.length;i++)
  85.                 {
  86.                         node=node.AddChild(allpath[i].trim());
  87.                 }
  88.         }
  89.        
  90.         public synchronized LinkedList<HashTreeNode> AddOneNode(String classpath)//加入节点
  91.         {//递归找到父节点
  92.                 LinkedList<HashTreeNode> result=new LinkedList<HashTreeNode>();
  93.                
  94.                 try
  95.                 {
  96.                 //System.out.println(classpath);

  97.                         for(String exc:excluded)
  98.                         {
  99.                                 if(classpath.contains(exc))
  100.                                 {
  101.                                         result.add(exception.AddChild(classpath));
  102.                                         return result;       
  103.                                 }
  104.                         }

  105.                         //接口看做父类
  106.                         java.lang.reflect.Type curtype=Class.forName(classpath).getGenericSuperclass();
  107.                         LinkedList<java.lang.reflect.Type> type=new LinkedList<java.lang.reflect.Type>();
  108.                         if(curtype != null)
  109.                                 type.add(curtype);
  110.                         else
  111.                                 result.add(root.AddChild(classpath));
  112.                         for(java.lang.reflect.Type curtype1:Class.forName(classpath).getGenericInterfaces())
  113.                         {
  114.                                 type.add(curtype1);
  115.                         }

  116.                         for(java.lang.reflect.Type curtype2:type)
  117.                         {
  118.                                 String classstr=curtype2.toString();
  119.                                 if(classstr.contains("interface") || classstr.contains("class"))
  120.                                         classstr=classstr.substring(classstr.indexOf(' ')+1);
  121.                                 if(classstr.indexOf('<') > -1)
  122.                                         classstr=classstr.substring(0,classstr.indexOf('<'));
  123.                                 for(HashTreeNode node1:AddOneNode(classstr))
  124.                                 {
  125.                                         result.add(node1.AddChild(classpath));
  126.                                 }
  127.                         }
  128.                         return result;       
  129.                 }
  130.                 catch(Exception e)
  131.                 {
  132.                         System.out.println("error:"+classpath);
  133.                         result.add(exception.AddChild(classpath));
  134.                         return result;
  135.                 }
  136.         }
  137.        
  138.         public static void FindClassInfo(String dir,String classpath)
  139.         {
  140.                 try
  141.                 {
  142.                         File file=new File(dir);
  143.                         if(file.isFile())
  144.                         {
  145.                                 if(classpath.indexOf('$') < 0 && classpath.indexOf(".class") > -1)
  146.                                 {
  147.                                         String obj=classpath.replace(".class","");
  148.                                         myqueue.add(obj);
  149.                                         System.out.println(obj);
  150.                                 }
  151.                         }
  152.                         else if(file.isDirectory())
  153.                         {
  154.                                 for(String dirstr:file.list())
  155.                                 {
  156.                                         String newclasspath=classpath.equals("")?dirstr:(classpath+"."+dirstr);
  157.                                         FindClassInfo(dir+"/"+dirstr,newclasspath);
  158.                                 }
  159.                         }
  160.                 }
  161.                 catch(Exception e)
  162.                 {
  163.                         System.out.println("error");
  164.                 }
  165.         }
  166.        
  167.         public void FindAllMatchClass(HashTreeNode node)
  168.         {
  169.                 try
  170.                 {
  171.                         String dest=tofind.substring(tofind.lastIndexOf('.')+1);
  172.                         if(node.nodename.contains(dest))
  173.                         {
  174.                                 ((DefaultListModel<String>)result.getModel()).addElement(node.nodename);
  175.                         }
  176.                         for(HashTreeNode cur:node.children)
  177.                         {
  178.                                 FindAllMatchClass(cur);
  179.                         }
  180.                 }
  181.                 catch(Exception e)
  182.                 {
  183.                         System.out.println("error");
  184.                 }
  185.         }
  186.        
  187.         public void AddUItree(HashTreeNode curnode,DefaultMutableTreeNode uinode)
  188.         {
  189.                 try
  190.                 {
  191.                         for(int i=0;i<curnode.children.size();i++)
  192.                         {
  193.                                 HashTreeNode cur=curnode.children.get(i);
  194.                                 DefaultMutableTreeNode newnode=new DefaultMutableTreeNode(cur.nodename);
  195.                                 uinode.add(newnode);
  196.                                 AddUItree(cur,newnode);
  197.                         }
  198.                 }
  199.                 catch(Exception e)
  200.                 {
  201.                         System.out.println("error");
  202.                 }
  203.         }
  204.        
  205.         public classtree()
  206.         {
  207.                 super("");
  208.                 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  209.                 getContentPane().setLayout(null);
  210.                
  211.                 toSearch = new JTextField();
  212.                 toSearch.setBounds(107, 630, 247, 21);
  213.                 getContentPane().add(toSearch);
  214.                 toSearch.setColumns(10);
  215.                
  216.                 JLabel label = new JLabel("\u8981\u641C\u7D22\u7684\u76EE\u6807\uFF1A");
  217.                 label.setBounds(10, 633, 87, 15);
  218.                 getContentPane().add(label);
  219.                
  220.                 JButton search = new JButton("\u641C");
  221.                 search.setBounds(364, 629, 100, 23);
  222.                 getContentPane().add(search);
  223.                
  224.                 scrollPane = new JScrollPane();
  225.                 scrollPane.setBounds(0, 0, 584, 496);
  226.                 getContentPane().add(scrollPane);
  227.                
  228.                 tree = new JTree();
  229.                 tree.setScrollsOnExpand(true);
  230.                 tree.setFocusable(true);
  231.                 tree.setAutoscrolls(true);
  232.                 tree.setModel(new DefaultTreeModel(uiroot=new DefaultMutableTreeNode("JAVAHOME")));
  233.                 scrollPane.setViewportView(tree);
  234.                
  235.                 JScrollPane scrollPane_1 = new JScrollPane();
  236.                 scrollPane_1.setBounds(0, 497, 584, 123);
  237.                 getContentPane().add(scrollPane_1);
  238.                
  239.                 result = new JList<String>();
  240.                 scrollPane_1.setViewportView(result);
  241.                
  242.                 JButton outputfile = new JButton("\u751F\u6210\u6587\u4EF6");
  243.                 outputfile.setBounds(474, 629, 100, 23);
  244.                 getContentPane().add(outputfile);
  245.                
  246.                 setSize(600,700);
  247.                 setVisible(true);
  248.                
  249.                 root=new HashTreeNode("根节点");
  250.                 exception=root.AddChild("异常");
  251.                 myqueue=new LinkedList<String>();
  252.                 select=new LinkedList<Integer>();
  253.                 excluded=new LinkedList<String>();
  254.                 excluded.add("com.sun.management.OperatingSystem");
  255.                 excluded.add("com.sun.org.apache.xml.internal.serialize.HTMLdtd");
  256.                 excluded.add("sun.awt.windows.WBufferStrategy");
  257.                 excluded.add("sun.font.FreetypeFontScaler");
  258.                 excluded.add("sun.java2d.cmm.lcms.LCMS");
  259.                 excluded.add("sun.jdbc.odbc.JdbcOdbcPlatform");
  260.                 excluded.add("sun.org.mozilla.javascript.internal.SecureCaller");
  261.                 excluded.add("sun.plugin.extension.ExtensionUtils");
  262.                 excluded.add("sun.plugin2.main.client.WDonatePrivilege");
  263.                 excluded.add("sun.plugin2.main.server.IExplorerPlugin");
  264.                 excluded.add("sun.plugin2.main.server.MozillaPlugin");
  265.                 excluded.add("sun.plugin2.os.windows.Windows");
  266.                 excluded.add("sun.plugin2.main.server.ProxySupport");
  267.                 excluded.add("sun.reflect.misc.Trampoline");
  268.                 excluded.add("sun.security.krb5.SCDynamicStoreConfig");
  269.                 excluded.add("oracle.jrockit.jfr.Process");
  270.                 excluded.add("oracle.jrockit.jfr.Timing");
  271.                 excluded.add("com.sun.deploy.uitoolkit.impl.awt.AWTClientPrintHelper");
  272.                 excluded.add("com.sun.glass.ui.mac");
  273.                 excluded.add("com.sun.glass.ui.x11.X11Timer");
  274.                 excluded.add("com.sun.javafx.logging.LoggingSupport");
  275.                
  276.                 try
  277.                 {
  278.                         if(new File("config.txt").exists())
  279.                         {
  280.                                 FileReader fr=new FileReader("config.txt");
  281.                                 BufferedReader br=new BufferedReader(fr);
  282.                                 FileInputStream fis=new FileInputStream("config.txt");
  283.                                 String line="";
  284.                                 while((line=br.readLine()) != null)
  285.                                 {
  286. //                                                                                                                                                                        System.out.println(line);
  287.                                         AddNodeByString(line.substring(1,line.length()-1).split(","));
  288.                                 }                                                               
  289.                                 br.close();
  290.                                 fr.close();
  291.                         }
  292.                 }
  293.                 catch(Exception e)
  294.                 {
  295.                         e.printStackTrace();
  296.                 }
  297.                
  298.                 result.addListSelectionListener(new ListSelectionListener()
  299.                 {
  300.                         public void valueChanged(ListSelectionEvent e)
  301.                         {
  302.                                 for(int i=0;i < tree.getRowCount();i++)
  303.                                 {
  304.                                         tree.expandRow(i);
  305.                                 }
  306.                                 int i=select.get(result.getSelectedIndex());
  307.                                 tree.setSelectionRow(i);
  308.                                 Rectangle rect=tree.getRowBounds(i);
  309.                                 tree.scrollRectToVisible(rect);
  310.                         }
  311.                 });
  312.                
  313.                 search.addMouseListener(new MouseAdapter()
  314.                 {
  315.                         Thread searchthread=null;
  316.                         @Override
  317.                         public void mouseClicked(MouseEvent e)
  318.                         {
  319.                                 searchthread=new Thread()
  320.                                 {//开始枚举文件线程
  321.                                         @Override
  322.                                         public void run()
  323.                                         {
  324.                                                 try
  325.                                                 {
  326.                                                         result.setModel(new DefaultListModel<String>());
  327.                                                         tofind=toSearch.getText();
  328.                                                         for(int i=0;i<tree.getRowCount();i++)
  329.                                                         {
  330.                                                                 tree.expandRow(i);
  331.                                                         }
  332.                                                         select=new LinkedList<Integer>();
  333.                                                         for(int i=0;i<tree.getRowCount();i++)
  334.                                                         {
  335.                                                                 String obj=tree.getPathForRow(i).toString();
  336.                                                                 if(obj.contains(tofind))
  337.                                                                 {
  338.                                                                         ((DefaultListModel<String>)result.getModel()).addElement(obj);
  339.                                                                         select.add(i);
  340.                                                                 }
  341.                                                         }
  342.                                                 }
  343.                                                 catch(Exception e)
  344.                                                 {
  345.                                                         e.printStackTrace();
  346.                                                 }
  347.                                         }
  348.                                 };
  349.                                
  350.                                 try
  351.                                 {
  352.                                         searchthread.start();
  353.                                         searchthread.join();                                                                                                                                               
  354.                                 }
  355.                                 catch(Exception exc)
  356.                                 {
  357.                                         exc.printStackTrace();
  358.                                 }
  359.                         }
  360.                 });
  361.                
  362.                 final Thread filethread=new Thread()
  363.                 {//开始枚举文件线程
  364.                         @Override
  365.                         public void run()
  366.                         {
  367.                                 FindClassInfo(folderpath,"");
  368.                                 datachanged=true;
  369.                         }
  370.                 };
  371.                 filethread.start();
  372.                
  373.                 new Thread()
  374.                 {//开始处理队列线程
  375.                         @Override
  376.                         public void run()
  377.                         {
  378.                                 try
  379.                                 {
  380.                                         filethread.join();
  381.                                         while(true)
  382.                                         {
  383.                                                 if(myqueue.isEmpty())
  384.                                                 {
  385.                                                         Thread.sleep(500);
  386.                                                         if(datachanged)
  387.                                                         {
  388.                                                                 uiroot=new DefaultMutableTreeNode("JAVAHOME");
  389.                                                                 tree.setModel(new DefaultTreeModel(uiroot));
  390.                                                                 AddUItree(root,uiroot);
  391.                                                                 datachanged=false;
  392.                                                         }
  393.                                                         else
  394.                                                         {
  395.                                                                 for(int i=0;i<tree.getRowCount();i++)
  396.                                                                 {
  397.                                                                         tree.expandRow(i);
  398.                                                                 }
  399.                                                         }
  400.                                                 }
  401.                                                 else
  402.                                                 {
  403.                                                         if(filethread.isAlive())
  404.                                                                 filethread.join();
  405.                                                         AddOneNode(myqueue.poll());
  406.                                                 }
  407.                                         }
  408.                                 }
  409.                                 catch(Exception e)
  410.                                 {
  411.                                         e.printStackTrace();
  412.                                 }                       
  413.                         }
  414.                 }.start();
  415.                
  416.                 outputfile.addMouseListener(new MouseAdapter()
  417.                 {
  418.                         @Override
  419.                         public void mouseClicked(MouseEvent e)
  420.                         {
  421.                                 OutputFile();
  422.                         }
  423.                 });
  424.                
  425.                 addWindowListener(new WindowAdapter()
  426.                 {//关闭时保存数据到文件
  427.                         @Override
  428.                         public void windowClosing(WindowEvent e)
  429.                         {
  430.                                 OutputFile();
  431.                         }
  432.                 });
  433.         }
  434.        
  435.         public void OutputFile()
  436.         {
  437.                 try
  438.                 {                                                                                                                                       
  439.                         for(int i=0;i < tree.getRowCount();i++)
  440.                         {
  441.                                 tree.expandRow(i);
  442.                         }
  443.                         FileOutputStream fos=new FileOutputStream("config.txt");
  444.                         for(int i=0;i<tree.getRowCount();i++)
  445.                         {
  446.                                 String obj=tree.getPathForRow(i).toString()+"\n";
  447.                                 fos.write(obj.getBytes());
  448.                         }
  449.                         fos.close();
  450.                 }
  451.                 catch(Exception e)
  452.                 {
  453.                         e.printStackTrace();
  454.                 }
  455.         }
  456.        
  457.         public static void main(String[] args) throws FileNotFoundException
  458.         {
  459.                 //System.setOut(new PrintStream("abcd.txt"));
  460.                 new classtree();
  461.         }
  462. }
复制代码

Config.txt样例部分:
[JAVAHOME]
[JAVAHOME, java.applet.AppletContext]
[JAVAHOME, java.applet.AppletContext, java.beans.BeansAppletContext]
[JAVAHOME, java.applet.AppletStub]
[JAVAHOME, java.applet.AppletStub, java.beans.BeansAppletStub]
[JAVAHOME, java.applet.AudioClip]
[JAVAHOME, java.awt.ActiveEvent]
[JAVAHOME, java.awt.ActiveEvent, java.awt.SentEvent]
[JAVAHOME, java.awt.ActiveEvent, java.awt.SequencedEvent]
[JAVAHOME, java.awt.ActiveEvent, java.awt.event.InvocationEvent]
[JAVAHOME, java.awt.Adjustable]
[JAVAHOME, java.awt.Adjustable, java.awt.ScrollPaneAdjustable]
[JAVAHOME, java.awt.Adjustable, java.awt.Scrollbar]
[JAVAHOME, java.awt.Adjustable, javax.swing.JScrollBar]
[JAVAHOME, java.awt.Composite]
[JAVAHOME, java.awt.Composite, java.awt.AlphaComposite]
工程文件:
test.rar (372.74 KB, 下载次数: 2)
回复

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-4-26 20:23 , Processed in 0.046307 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表