以前有段时间需要知道某些类在什么jar包中,这样当出现ClassNotFoundException或者NoClassDefFoundError的时候我们就可以去找这个类在什么jar包中然后去引用此jar包即可。在我们的系统很小的时候我恨不能都将jar包放入eclipse中,这样借助eclipse平台查找类就非常方便了。包括非常有用的Ctrl+Shift+T,Ctrl+T,Reference search等等,但是当工程多了大了的时候,上百个jar包放入eclipse中那个速度完全不是我能忍受的,稍微动一下就看到CPU一直在那抖动。好吧,用maven,更慢,简直受不了,所以大多数时候Maven是一个比较好的批处理工具,和UI结合起来还不是很好用。
我发现我非常需要这个从jar包中寻找类的功能,我只需要看看我的类在什么地方而已,仅次而已!于是自己就写了一个类查找器。非常简单就是遍历所有的jar包中的类,当匹配类名称的时候就显示类所在的jar包。
有以下几个特性:
- 允许添加jar包,zip包
- 允许匹配包名称
- 允许匹配类名称
- 允许区分大小写
- 支持模糊查找(包括*和?)
- 自动匹配(输入完成后就匹配)
- 关闭后保存所有jar包结果(下次启动无需再次扫描)
- 完全内存查找,速度飞快
看下面的几张截图。
这个是4个多月前临时的东西,花了一个下午,用了几天解决了问题后就基本不用了,所以一直没有维护,于是就放出来了。有需要的同学就可以看看。
由于当初只是临时用用,所以就写得非常乱,凑合着用了。
分析几段源码吧。完整的源码在附件中。
http://www.blogjava.net/Files/xylz/xylz-classfinder.zip
这里还有一个我使用过的exe程序(Windows 版)。
http://www.blogjava.net/Files/xylz/xylzcf_0.0.1.0011.zip
下面是一段字符串匹配的代码(这段代码应该是前几年我从
apache ant中摘取出来的,后来移到我的工具包中了,我觉得这对逻辑太复杂,所以一直没怎么研究,但是确实效率不错,而且没有发现使用错误。)
1 public static boolean match(String pattern, String str, boolean isCaseSensitive) {
2 char[] patArr = pattern.toCharArray();
3 char[] strArr = str.toCharArray();
4 int patIdxStart = 0;
5 int patIdxEnd = patArr.length - 1;
6 int strIdxStart = 0;
7 int strIdxEnd = strArr.length - 1;
8 char ch;
9
10 boolean containsStar = false;
11 for (int i = 0; i < patArr.length; i++) {
12 if (patArr[i] == '*') {
13 containsStar = true;
14 break;
15 }
16 }
17
18 if (!containsStar) {
19 // No '*'s, so we make a shortcut
20 if (patIdxEnd != strIdxEnd) {
21 return false; // Pattern and string do not have the same size
22 }
23 for (int i = 0; i <= patIdxEnd; i++) {
24 ch = patArr[i];
25 if (ch != '?') {
26 if (isCaseSensitive && ch != strArr[i]) {
27 return false; // Character mismatch
28 }
29 if (!isCaseSensitive
30 && Character.toUpperCase(ch) != Character.toUpperCase(strArr[i])) {
31 return false; // Character mismatch
32 }
33 }
34 }
35 return true; // String matches against pattern
36 }
37
38 if (patIdxEnd == 0) {
39 return true; // Pattern contains only '*', which matches anything
40 }
41
42 // Process characters before first star
43 while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) {
44 if (ch != '?') {
45 if (isCaseSensitive && ch != strArr[strIdxStart]) {
46 return false; // Character mismatch
47 }
48 if (!isCaseSensitive
49 && Character.toUpperCase(ch) != Character.toUpperCase(strArr[strIdxStart])) {
50 return false; // Character mismatch
51 }
52 }
53 patIdxStart++;
54 strIdxStart++;
55 }
56 if (strIdxStart > strIdxEnd) {
57 // All characters in the string are used. Check if only '*'s are
58 // left in the pattern. If so, we succeeded. Otherwise failure.
59 for (int i = patIdxStart; i <= patIdxEnd; i++) {
60 if (patArr[i] != '*') {
61 return false;
62 }
63 }
64 return true;
65 }
66
67 // Process characters after last star
68 while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) {
69 if (ch != '?') {
70 if (isCaseSensitive && ch != strArr[strIdxEnd]) {
71 return false; // Character mismatch
72 }
73 if (!isCaseSensitive
74 && Character.toUpperCase(ch) != Character.toUpperCase(strArr[strIdxEnd])) {
75 return false; // Character mismatch
76 }
77 }
78 patIdxEnd--;
79 strIdxEnd--;
80 }
81 if (strIdxStart > strIdxEnd) {
82 // All characters in the string are used. Check if only '*'s are
83 // left in the pattern. If so, we succeeded. Otherwise failure.
84 for (int i = patIdxStart; i <= patIdxEnd; i++) {
85 if (patArr[i] != '*') {
86 return false;
87 }
88 }
89 return true;
90 }
91
92 // process pattern between stars. padIdxStart and patIdxEnd point
93 // always to a '*'.
94 while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
95 int patIdxTmp = -1;
96 for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
97 if (patArr[i] == '*') {
98 patIdxTmp = i;
99 break;
100 }
101 }
102 if (patIdxTmp == patIdxStart + 1) {
103 // Two stars next to each other, skip the first one.
104 patIdxStart++;
105 continue;
106 }
107 // Find the pattern between padIdxStart & padIdxTmp in str between
108 // strIdxStart & strIdxEnd
109 int patLength = (patIdxTmp - patIdxStart - 1);
110 int strLength = (strIdxEnd - strIdxStart + 1);
111 int foundIdx = -1;
112 strLoop: for (int i = 0; i <= strLength - patLength; i++) {
113 for (int j = 0; j < patLength; j++) {
114 ch = patArr[patIdxStart + j + 1];
115 if (ch != '?') {
116 if (isCaseSensitive && ch != strArr[strIdxStart + i + j]) {
117 continue strLoop;
118 }
119 if (!isCaseSensitive
120 && Character.toUpperCase(ch) != Character
121 .toUpperCase(strArr[strIdxStart + i + j])) {
122 continue strLoop;
123 }
124 }
125 }
126
127 foundIdx = strIdxStart + i;
128 break;
129 }
130
131 if (foundIdx == -1) {
132 return false;
133 }
134
135 patIdxStart = patIdxTmp;
136 strIdxStart = foundIdx + patLength;
137 }
138
139 // All characters in the string are used. Check if only '*'s are left
140 // in the pattern. If so, we succeeded. Otherwise failure.
141 for (int i = patIdxStart; i <= patIdxEnd; i++) {
142 if (patArr[i] != '*') {
143 return false;
144 }
145 }
146 return true;
147 }
148
149 static void print(File jarFile) throws Exception {
150 JarFile file = new JarFile(jarFile);
151 for (JarEntry e : Collections.list(file.entries())) {
152 System.out.println(e.getName());
153 }
154 }
java swing中当光标定位文本框时自动选中其内容的代码。
1 cnameText.addFocusListener(new FocusAdapter() {
2 @Override
3 public void focusGained(FocusEvent e) {
4 if(cnameText.getText().length()>0) {
5 cnameText.setSelectionStart(0);
6 cnameText.setSelectionEnd(cnameText.getText().length());
7 }
8 }
9 });
当文本框中有输入变化时触发更新列表动作。早期的做法是将doText放入线程中这样防止GUI卡死,但是在这个例子中由于太快了,所以就没有新起线程。
1 cnameText.getDocument().addDocumentListener(new DocumentListener() {
2
3 @Override
4 public void changedUpdate(DocumentEvent e) {
5 doText(cnameText.getText());
6 }
7
8 @Override
9 public void insertUpdate(DocumentEvent e) {
10 doText(cnameText.getText());
11 }
12
13 @Override
14 public void removeUpdate(DocumentEvent e) {
15 doText(cnameText.getText());
16 }
17 });
遍历一个jar包中所有类的过程。
1 List<JarEntry> list = Collections.list(new JarFile(jarFile).entries());
2 List<String> fullNames = new ArrayList<String>();
3 for (JarEntry e : list) {
4 String n = e.getName();
5 if (n.endsWith(".class")) {
6 n=n.substring(0,n.length()-6);
7 fullNames.add(n.replace('/', '.'));
8 }
9 }
10 classCount = fullNames.size();
11 classNames = fullNames.toArray(new String[classCount]);
大概这么多吧,写得很乱,看的也很累!!!
©2009-2014 IMXYLZ
|求贤若渴