1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.xmlhammer.gui.output;
23
24 import java.awt.Color;
25 import java.awt.LayoutManager;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28
29 import javax.swing.JPanel;
30 import javax.swing.text.BadLocationException;
31 import javax.swing.text.DefaultHighlighter;
32 import javax.swing.text.JTextComponent;
33 import javax.swing.text.Highlighter.Highlight;
34
35 import org.apache.log4j.Logger;
36
37 /***
38 * A search-able Panel.
39 *
40 * @version $Revision$, $Date$
41 * @author Edwin Dankert <edankert@gmail.com>
42 */
43
44 public abstract class SearchablePanel extends JPanel {
45 public SearchablePanel() {
46 super();
47 }
48
49 public SearchablePanel(boolean arg0) {
50 super(arg0);
51 }
52
53 public SearchablePanel(LayoutManager arg0, boolean arg1) {
54 super(arg0, arg1);
55 }
56
57 public SearchablePanel(LayoutManager arg0) {
58 super(arg0);
59 }
60
61 public abstract boolean search(String search, boolean matchCase, boolean forward);
62
63 protected static boolean search(JTextComponent text, String search, boolean matchCase, boolean forward) {
64 Pattern pattern = null;
65 String regularSearch = "//Q"+prepareNonRegularExpression(search)+"//E";
66
67 int start = -1;
68 int end = -1;
69
70 if (!matchCase) {
71 pattern = Pattern.compile( regularSearch, Pattern.CASE_INSENSITIVE);
72 } else {
73 pattern = Pattern.compile( regularSearch);
74 }
75
76 try {
77 int caret = text.getCaretPosition();
78
79 if (getHiglight(text) != null) {
80 caret = Math.max(caret, Math.max(getHighlightStart(text), getHighlightEnd(text)));
81 }
82
83 Matcher matcher = pattern.matcher(text.getText(0, text.getDocument().getLength()));
84
85 if (forward) {
86 boolean match = matcher.find(caret);
87
88
89 if (!match) {
90 match = matcher.find(0);
91 }
92
93 if (match) {
94 start = matcher.start();
95 end = matcher.end();
96 }
97 } else {
98 caret = text.getCaretPosition();
99
100 if (getHiglight(text) != null) {
101 caret = Math.min(caret, Math.min(getHighlightStart(text), getHighlightEnd(text)));
102 }
103
104 while (matcher.find()) {
105 if (matcher.start() < caret) {
106 start = matcher.start();
107 end = matcher.end();
108 } else {
109 break;
110 }
111 }
112
113 if (start == -1) {
114 boolean match = matcher.find(caret);
115
116 while (match) {
117 start = matcher.start();
118 end = matcher.end();
119
120 match = matcher.find();
121 }
122 }
123 }
124
125 if (end != -1) {
126 matcher.find(start);
127 select(text, start, end);
128 }
129
130 text.repaint();
131 } catch(Exception e) {
132 e.printStackTrace();
133 }
134
135 return end != -1;
136 }
137
138 private static String prepareNonRegularExpression(String regexp) {
139 StringBuffer result = new StringBuffer(regexp);
140
141 if (result.length() > 0) {
142 int index = result.indexOf("//E");
143
144 while (index != -1) {
145 result.replace(index, index+2, "//E////E//Q");
146 index = result.indexOf("//E", index+7);
147 }
148
149
150
151 if (result.charAt(result.length()-1) == '//') {
152 result.append("E//////Q");
153 }
154 }
155
156 return result.toString();
157 }
158
159 private static void select(JTextComponent text, int start, int end) {
160 try {
161 if (start > 0) {
162 text.getHighlighter().removeAllHighlights();
163 text.getHighlighter().addHighlight(start, end, new DefaultHighlighter.DefaultHighlightPainter(brighter(text.getSelectionColor())));
164 }
165 } catch (BadLocationException e) {
166 Logger.getLogger(SearchablePanel.class).debug(e);
167 }
168 text.setCaretPosition(Math.max(0, end));
169 }
170
171 private static int getHighlightStart(JTextComponent text) {
172 Highlight highlight = getHiglight(text);
173
174 if (highlight != null) {
175 return highlight.getStartOffset();
176 }
177
178 return -1;
179 }
180
181 private static int getHighlightEnd(JTextComponent text) {
182 Highlight highlight = getHiglight(text);
183
184 if (highlight != null) {
185 return highlight.getEndOffset();
186 }
187
188 return -1;
189 }
190
191 private static Highlight getHiglight(JTextComponent text) {
192 Highlight[] highlights = text.getHighlighter().getHighlights();
193
194 if (highlights.length > 0) {
195 return highlights[0];
196 }
197
198 return null;
199 }
200
201 private static Color brighter(Color color) {
202 return new Color(brighten(color.getRed()), brighten(color.getGreen()), brighten(color.getBlue()));
203 }
204
205 private static int brighten(int color) {
206 int newColor = color * (100 + 10) / 100;
207
208
209 if ( newColor >= 0xFF) {
210 newColor = 0xFF;
211
212
213 } else if ( newColor == color) {
214 newColor++;
215 }
216
217 return newColor;
218 }
219 }