1 importjava.awt.Color;2 importjava.util.Set;3
4 importjavax.swing.JTextPane;5 importjavax.swing.SwingUtilities;6 importjavax.swing.event.DocumentEvent;7 importjavax.swing.event.DocumentListener;8 importjavax.swing.text.AttributeSet;9 importjavax.swing.text.BadLocationException;10 importjavax.swing.text.Document;11 importjavax.swing.text.MutableAttributeSet;12 importjavax.swing.text.SimpleAttributeSet;13 importjavax.swing.text.Style;14 importjavax.swing.text.StyleConstants;15 importjavax.swing.text.StyledDocument;16
17 /**
18 * 自定义的JTextPane,扩展了JTextPane没有的一些功能(java关键字、单行注释、多行注释加亮)19 *20 *@authormyafluy@gmail.com21 *@since2013-08-1722 *23 */
24
25 public class MyJTextPane extends JTextPane implementsDocumentListener {26 private Setkeywords;27 privateStyle keywordStyle;28 privateStyle normalStyle;29 privateStyle classNameStyle;30
31 publicMyJTextPane() {32 super();33 this.getDocument().addDocumentListener(this);34 //准备着色使用的样式
35 keywordStyle =((StyledDocument) getDocument()).addStyle(36 "Keyword_Style", null);37 normalStyle =((StyledDocument) getDocument()).addStyle(38 "Keyword_Style", null);39
40 StyleConstants.setForeground(keywordStyle, Color.RED);41
42 StyleConstants.setForeground(normalStyle, Color.BLACK);43
44 //获取关键字
45 keywords =KeyWordSet.getKeyWordSet();46 System.out.println(keywords.size());47
48 }49
50 /**
51 * 设置全文本属性52 *53 *@paramattr54 *@paramreplace55 */
56 public void setTextAttributes(AttributeSet attr, booleanreplace) {57 int p0 = 0;58 int p1 = this.getText().length();59 if (p0 !=p1) {60 StyledDocument doc =getStyledDocument();61 doc.setCharacterAttributes(p0, p1 -p0, attr, replace);62 } else{63 MutableAttributeSet inputAttributes =getInputAttributes();64 if(replace) {65 inputAttributes.removeAttributes(inputAttributes);66 }67 inputAttributes.addAttributes(attr);68 }69 }70
71 /**
72 * 单行注释73 */
74 public voidsetSingleLineNoteCharacterAttributes() {75 String text = this.getText();76 int startPointer = 0;77 int endPointer = 0;78 if ((startPointer = text.indexOf("//")) == -1) {79 return;80 }81
82 while ((endPointer = text.substring(startPointer).indexOf("\n")) != -1) {83 endPointer = startPointer +endPointer;84 if (startPointer >=endPointer) {85 break;86 }87 int hangshu = text.substring(0, endPointer).split("\\n").length;88 System.out.println("hangshu:" +hangshu);89 SwingUtilities90 .invokeLater(new ColouringWord(this, startPointer -hangshu91 + 1, endPointer - hangshu, new Color(63, 217, 95)));92 startPointer = text.substring(endPointer + 1).indexOf("//");93 startPointer = startPointer + endPointer + 1;94
95 }96 }97
98 /**
99 * 多行注释100 */
101 public voidsetMultiLineNoteCharacterAttributes() {102 String text = this.getText();103 int startPointer = 0;104 int endPointer = 0;105 if ((startPointer = text.indexOf("/*")) == -1) {106 return;107 }108
109 while ((endPointer = text.substring(startPointer).indexOf("*/")) != -1) {110 endPointer = startPointer +endPointer;111 if (startPointer >=endPointer) {112 break;113 }114 int hangshu = text.substring(0, endPointer).split("\\n").length;115 int kuaju = text.substring(startPointer, endPointer).split("\\n").length;116 SwingUtilities.invokeLater(new ColouringWord(this, startPointer117 - hangshu + kuaju, endPointer + 3 - hangshu, new Color(63,118 217, 95)));119 startPointer = text.substring(endPointer + 1).indexOf("/*");120 startPointer = startPointer + endPointer + 1;121
122 }123 }124
125 /**
126 * 实时加亮关键字127 *@paramstyledDocument128 *@parampos129 *@paramlen130 *@throwsBadLocationException131 */
132 public void myColouring(StyledDocument styledDocument, int pos, intlen)133 throwsBadLocationException {134 int start =indexOfWordStart(styledDocument, pos);135 int end = indexOfWordEnd(styledDocument, pos +len);136
137 charch;138 while (start
141 start =myColouringWord(styledDocument, start);142 } else{143 SwingUtilities.invokeLater(newColouringTask(styledDocument,144 start, 1, normalStyle));145 ++start;146 }147 }148 }149
150 /**
151 * 实时着色152 *153 *@paramdoc154 *@parampos155 *@return
156 *@throwsBadLocationException157 */
158 public int myColouringWord(StyledDocument doc, intpos)159 throwsBadLocationException {160 int wordEnd =indexOfWordEnd(doc, pos);161 String word = doc.getText(pos, wordEnd -pos);162
163 if(keywords.contains(word)) {164 SwingUtilities.invokeLater(newColouringTask(doc, pos, wordEnd165 -pos, keywordStyle));166 } else{167 SwingUtilities.invokeLater(newColouringTask(doc, pos, wordEnd168 -pos, normalStyle));169 }170
171 returnwordEnd;172 }173
174 /**
175 * 取得在文档中下标在pos处的字符.176 *177 *@paramdoc178 *@parampos179 *@return
180 *@throwsBadLocationException181 */
182 public char getCharAt(Document doc, int pos) throwsBadLocationException {183 return doc.getText(pos, 1).charAt(0);184 }185
186 /**
187 * 取得下标为pos时, 它所在的单词开始的下标.188 *189 *@paramdoc190 *@parampos191 *@return
192 *@throwsBadLocationException193 */
194 public int indexOfWordStart(Document doc, intpos)195 throwsBadLocationException {196 //从pos开始向前找到第一个非单词字符.
197 for (; pos > 0 && isWordCharacter(doc, pos - 1); --pos)198 ;199
200 returnpos;201 }202
203 /**
204 * 取得下标为pos时, 它所在的单词结束的下标.205 *206 *@paramdoc207 *@parampos208 *@return
209 *@throwsBadLocationException210 */
211 public int indexOfWordEnd(Document doc, intpos)212 throwsBadLocationException {213 //从pos开始向前找到第一个非单词字符.
214 for (; isWordCharacter(doc, pos); ++pos)215 ;216
217 returnpos;218 }219
220 /**
221 * 如果一个字符是字母, 数字, 下划线, 则返回true.222 *223 *@paramdoc224 *@parampos225 *@return
226 *@throwsBadLocationException227 */
228 public boolean isWordCharacter(Document doc, intpos)229 throwsBadLocationException {230 char ch =getCharAt(doc, pos);231 if (Character.isLetter(ch) || Character.isDigit(ch) || ch == '_') {232 return true;233 }234 return false;235 }236
237 @Override238 //给出属性或属性集发生了更改的通知
239 public voidchangedUpdate(DocumentEvent e) {240
241 }242
243 @Override244 //给出对文档执行了插入操作的通知
245 public voidinsertUpdate(DocumentEvent e) {246 try{247 myColouring((StyledDocument) e.getDocument(), e.getOffset(),248 e.getLength());249 //noteFinder.ColorNote(this.getText());//给注释上色
250 setSingleLineNoteCharacterAttributes();251 setMultiLineNoteCharacterAttributes();252 } catch(BadLocationException e1) {253 e1.printStackTrace();254 }255 }256
257 @Override258 //给出移除了一部分文档的通知
259 public voidremoveUpdate(DocumentEvent e) {260 try{261 //因为删除后光标紧接着影响的单词两边, 所以长度就不需要了
262 myColouring((StyledDocument) e.getDocument(), e.getOffset(), 0);263 //noteFinder.ColorNote(this.getText());//给注释上色
264 setSingleLineNoteCharacterAttributes();265 setMultiLineNoteCharacterAttributes();266 } catch(BadLocationException e1) {267 e1.printStackTrace();268 }269 }270
271 /**
272 * 多线程绘制颜色273 *274 *275 *276 */
277 private class ColouringTask implementsRunnable {278 privateStyledDocument doc;279 privateStyle style;280 private intpos;281 private intlen;282
283 public ColouringTask(StyledDocument doc, int pos, intlen, Style style) {284 this.doc =doc;285 this.pos =pos;286 this.len =len;287 this.style =style;288 }289
290 public voidrun() {291 try{292 //这里就是对字符进行着色
293 doc.setCharacterAttributes(pos, len, style, false);294 } catch(Exception e) {295 }296 }297 }298
299 }300
301 /**
302 * 多线程绘制颜色303 *304 *305 *306 */
307 class ColouringWord implementsRunnable {308 private intstartPointer;309 private intendPointer;310 privateColor color;311 privateJTextPane jTextPane;312
313 public ColouringWord(JTextPane jTextPane, int pos, intlen, Color color) {314 this.jTextPane =jTextPane;315 this.startPointer =pos;316 this.endPointer =len;317 this.color =color;318 }319
320 @Override321 public voidrun() {322 SimpleAttributeSet attributeSet = newSimpleAttributeSet();323 StyleConstants.setForeground(attributeSet, color);324 boolean replace = false;325 int p0 =startPointer;326 int p1 =endPointer;327 if (p0 !=p1) {328 StyledDocument doc =jTextPane.getStyledDocument();329 doc.setCharacterAttributes(p0, p1 -p0, attributeSet, replace);330 } else{331 MutableAttributeSet inputAttributes =jTextPane332 .getInputAttributes();333 if(replace) {334 inputAttributes.removeAttributes(inputAttributes);335 }336 inputAttributes.addAttributes(attributeSet);337 }338 }339 }