以前有段時(shí)間需要知道某些類在什么jar包中,這樣當(dāng)出現(xiàn)ClassNotFoundException或者NoClassDefFoundError的時(shí)候我們就可以去找這個(gè)類在什么jar包中然后去引用此jar包即可。在我們的系統(tǒng)很小的時(shí)候我恨不能都將jar包放入eclipse中,這樣借助eclipse平臺(tái)查找類就非常方便了。包括非常有用的Ctrl+Shift+T,Ctrl+T,Reference search等等,但是當(dāng)工程多了大了的時(shí)候,上百個(gè)jar包放入eclipse中那個(gè)速度完全不是我能忍受的,稍微動(dòng)一下就看到CPU一直在那抖動(dòng)。好吧,用maven,更慢,簡(jiǎn)直受不了,所以大多數(shù)時(shí)候Maven是一個(gè)比較好的批處理工具,和UI結(jié)合起來(lái)還不是很好用。
我發(fā)現(xiàn)我非常需要這個(gè)從jar包中尋找類的功能,我只需要看看我的類在什么地方而已,僅次而已!于是自己就寫了一個(gè)類查找器。非常簡(jiǎn)單就是遍歷所有的jar包中的類,當(dāng)匹配類名稱的時(shí)候就顯示類所在的jar包。
有以下幾個(gè)特性:
- 允許添加jar包,zip包
- 允許匹配包名稱
- 允許匹配類名稱
- 允許區(qū)分大小寫
- 支持模糊查找(包括*和?)
- 自動(dòng)匹配(輸入完成后就匹配)
- 關(guān)閉后保存所有jar包結(jié)果(下次啟動(dòng)無(wú)需再次掃描)
- 完全內(nèi)存查找,速度飛快
看下面的幾張截圖。
這個(gè)是4個(gè)多月前臨時(shí)的東西,花了一個(gè)下午,用了幾天解決了問(wèn)題后就基本不用了,所以一直沒(méi)有維護(hù),于是就放出來(lái)了。有需要的同學(xué)就可以看看。
由于當(dāng)初只是臨時(shí)用用,所以就寫得非常亂,湊合著用了。
分析幾段源碼吧。完整的源碼在附件中。
http://m.tkk7.com/Files/xylz/xylz-classfinder.zip
這里還有一個(gè)我使用過(guò)的exe程序(Windows 版)。
http://m.tkk7.com/Files/xylz/xylzcf_0.0.1.0011.zip
下面是一段字符串匹配的代碼(這段代碼應(yīng)該是前幾年我從
apache ant中摘取出來(lái)的,后來(lái)移到我的工具包中了,我覺(jué)得這對(duì)邏輯太復(fù)雜,所以一直沒(méi)怎么研究,但是確實(shí)效率不錯(cuò),而且沒(méi)有發(fā)現(xiàn)使用錯(cuò)誤。)
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中當(dāng)光標(biāo)定位文本框時(shí)自動(dòng)選中其內(nèi)容的代碼。
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 });
當(dāng)文本框中有輸入變化時(shí)觸發(fā)更新列表動(dòng)作。早期的做法是將doText放入線程中這樣防止GUI卡死,但是在這個(gè)例子中由于太快了,所以就沒(méi)有新起線程。
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 });
遍歷一個(gè)jar包中所有類的過(guò)程。
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
|求賢若渴