【java】【swing】【JTextPane】自定义的JTextPane,扩展了JTextPane没有的一些功能(java关键字、单行注释、多行注释加亮)

  1 import java.awt.Color;

  2 import java.util.Set;

  3 

  4 import javax.swing.JTextPane;

  5 import javax.swing.SwingUtilities;

  6 import javax.swing.event.DocumentEvent;

  7 import javax.swing.event.DocumentListener;

  8 import javax.swing.text.AttributeSet;

  9 import javax.swing.text.BadLocationException;

 10 import javax.swing.text.Document;

 11 import javax.swing.text.MutableAttributeSet;

 12 import javax.swing.text.SimpleAttributeSet;

 13 import javax.swing.text.Style;

 14 import javax.swing.text.StyleConstants;

 15 import javax.swing.text.StyledDocument;

 16 

 17 /**

 18  * 自定义的JTextPane,扩展了JTextPane没有的一些功能(java关键字、单行注释、多行注释加亮)

 19  * 

 20  * @author [email protected]

 21  * @since 2013-08-17

 22  * 

 23  */

 24 

 25 public class MyJTextPane extends JTextPane implements DocumentListener {

 26     private Set<String> keywords;

 27     private Style keywordStyle;

 28     private Style normalStyle;

 29     private Style classNameStyle;

 30 

 31     public MyJTextPane() {

 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      * @param attr

 54      * @param replace

 55      */

 56     public void setTextAttributes(AttributeSet attr, boolean replace) {

 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 void setSingleLineNoteCharacterAttributes() {

 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             SwingUtilities

 90                     .invokeLater(new ColouringWord(this, startPointer - hangshu

 91                             + 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 void setMultiLineNoteCharacterAttributes() {

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, startPointer

117                     - 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      * @param styledDocument

128      * @param pos

129      * @param len

130      * @throws BadLocationException

131      */

132     public void myColouring(StyledDocument styledDocument, int pos, int len)

133             throws BadLocationException {

134         int start = indexOfWordStart(styledDocument, pos);

135         int end = indexOfWordEnd(styledDocument, pos + len);

136 

137         char ch;

138         while (start < end) {

139             ch = getCharAt(styledDocument, start);

140             if (Character.isLetter(ch) || ch == '_') {//判断是否为字母

141                 start = myColouringWord(styledDocument, start);

142             } else {

143                 SwingUtilities.invokeLater(new ColouringTask(styledDocument,

144                         start, 1, normalStyle));

145                 ++start;

146             }

147         }

148     }

149 

150     /**

151      * 实时着色

152      * 

153      * @param doc

154      * @param pos

155      * @return

156      * @throws BadLocationException

157      */

158     public int myColouringWord(StyledDocument doc, int pos)

159             throws BadLocationException {

160         int wordEnd = indexOfWordEnd(doc, pos);

161         String word = doc.getText(pos, wordEnd - pos);

162 

163         if (keywords.contains(word)) {

164             SwingUtilities.invokeLater(new ColouringTask(doc, pos, wordEnd

165                     - pos, keywordStyle));

166         } else {

167             SwingUtilities.invokeLater(new ColouringTask(doc, pos, wordEnd

168                     - pos, normalStyle));

169         }

170 

171         return wordEnd;

172     }

173 

174     /**

175      * 取得在文档中下标在pos处的字符.

176      * 

177      * @param doc

178      * @param pos

179      * @return

180      * @throws BadLocationException

181      */

182     public char getCharAt(Document doc, int pos) throws BadLocationException {

183         return doc.getText(pos, 1).charAt(0);

184     }

185 

186     /**

187      * 取得下标为pos时, 它所在的单词开始的下标.

188      * 

189      * @param doc

190      * @param pos

191      * @return

192      * @throws BadLocationException

193      */

194     public int indexOfWordStart(Document doc, int pos)

195             throws BadLocationException {

196         // 从pos开始向前找到第一个非单词字符.

197         for (; pos > 0 && isWordCharacter(doc, pos - 1); --pos)

198             ;

199 

200         return pos;

201     }

202 

203     /**

204      * 取得下标为pos时, 它所在的单词结束的下标.

205      * 

206      * @param doc

207      * @param pos

208      * @return

209      * @throws BadLocationException

210      */

211     public int indexOfWordEnd(Document doc, int pos)

212             throws BadLocationException {

213         // 从pos开始向前找到第一个非单词字符.

214         for (; isWordCharacter(doc, pos); ++pos)

215             ;

216 

217         return pos;

218     }

219 

220     /**

221      * 如果一个字符是字母, 数字, 下划线, 则返回true.

222      * 

223      * @param doc

224      * @param pos

225      * @return

226      * @throws BadLocationException

227      */

228     public boolean isWordCharacter(Document doc, int pos)

229             throws BadLocationException {

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     @Override

238     // 给出属性或属性集发生了更改的通知

239     public void changedUpdate(DocumentEvent e) {

240 

241     }

242 

243     @Override

244     // 给出对文档执行了插入操作的通知

245     public void insertUpdate(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     @Override

258     // 给出移除了一部分文档的通知

259     public void removeUpdate(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 implements Runnable {

278         private StyledDocument doc;

279         private Style style;

280         private int pos;

281         private int len;

282 

283         public ColouringTask(StyledDocument doc, int pos, int len, Style style) {

284             this.doc = doc;

285             this.pos = pos;

286             this.len = len;

287             this.style = style;

288         }

289 

290         public void run() {

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 implements Runnable {

308     private int startPointer;

309     private int endPointer;

310     private Color color;

311     private JTextPane jTextPane;

312 

313     public ColouringWord(JTextPane jTextPane, int pos, int len, Color color) {

314         this.jTextPane = jTextPane;

315         this.startPointer = pos;

316         this.endPointer = len;

317         this.color = color;

318     }

319 

320     @Override

321     public void run() {

322         SimpleAttributeSet attributeSet = new SimpleAttributeSet();

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 = jTextPane

332                     .getInputAttributes();

333             if (replace) {

334                 inputAttributes.removeAttributes(inputAttributes);

335             }

336             inputAttributes.addAttributes(attributeSet);

337         }

338     }

339 }

 

你可能感兴趣的:(java关键字)