• 【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 myafluy@gmail.com
     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("
    ")) != -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 }
  • 相关阅读:
    Git轻松入门3:远程仓库篇
    Git轻松入门2:分支篇
    Git轻松入门1:本地仓库篇
    通俗易懂的解释:什么是API
    小白都看得懂的Javadoc使用教程
    尾调用与尾递归
    要理解递归就要先理解递归:手把手教你写递归
    不复杂的空间复杂度
    不复杂的时间复杂度
    Java程序执行过程及内存机制
  • 原文地址:https://www.cnblogs.com/afluy/p/3265024.html
Copyright © 2020-2023  润新知