<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 4, 文章 - 1, 評論 - 22, 引用 - 0
    數據加載中……

    Swing實現Java代碼編輯器 - 語法高亮顯示

        本文主要記錄怎么給代碼編輯器實際語法高亮顯示的功能,先來張效果圖吧:
        
        

        當JEditorPane被創建時,它會把createDefaultEditorKit()方法(javax.swing.text.EditorKit的子類對象)的返回值作為默認的編輯器工具包,然后將文本的編輯與顯示工作交給這個工具包。其原型為:
    1protected EditorKit createDefaultEditorKit()
    2{
    3    return new PlainEditorKit();
    4}
        這個方法默認是返回一個PlainEditorKit對象,也就是一個純文本的編輯器工具包,所以JEditorPane默認并沒有格式化與彩色顯示等功能,看來我們先要定制一個支持彩色顯示的EditorKit,然后把它作為createDefaultEditorKit()的返回值。

    EditorKit基本上什么也沒有做,只是提供了很多抽象方法給它的子類去實現,Swing默認已經給它添加了一個子類DefaultEditorKit(Swing常用的一招,就是給抽象類前面加個Default進行最基本的實現),既然是Default,那它所提供的功能肯定和一個記事本沒有多大區別,這要是繼承下來,有多少方法需要覆蓋啊,別慌,查看一下Swing的源碼,你會發現Swing還提供了一個繼承自DefaultEditorKit的類StyledEditorKit,顧名思義,這個類肯定為我們提供了很多支持格式化顯示的方法,又是一個巨人,快,趕緊拉過來往肩上爬。
        接下來就是覆蓋StyledEditorKit中的相關方法了,其實有很多方法都可以覆蓋,但是意義不是很大,比如
    public String getContentType();
        這個方法是獲得此工具包聲明支持的數據的 MIME 類型,默認是text/plain,也就是文本文檔,Java文件說白了也是文本文檔,不過可以讓它返回 text/java 以唯一標識編輯器所支持的MIME類型。

    EditorKit中有兩個重要的方法實現對文檔的管理與顯示:

    public abstract Document createDefaultDocument();

    創建一個適合此編輯器類型文本存儲模型。EditorKit把對文本文檔的管理功能交給了這個方法的返回值。

    public abstract ViewFactory getViewFactory();

    獲取適合生成此工具包生成的任何模型視圖的工廠。EditorKit把編輯器的顯示功能交給了這個方法的返回值,比如什么字符顯示成什么樣子,什么顏色等。我們必須覆蓋這兩個方法以實現自定義編輯器的功能。

    因為我們的編輯器和JEditorPane唯一不同的可能就是代碼怎么來顯示,所以createDefaultDocument()可以返回一個默認的javax.swing.text.DefaultStyledDocument 就行,對于getViewFactory,我們需要定制一個ViewFactory視圖來實現編輯器獨有的各種顯示功能。

    ViewFactory在Java中被定義為一個接口,里面提供了唯一的一個方法:

    public View create(Element elem);

    這個方法根據給定的文檔的結構化元素創建一個視圖。在這個方法中,我們只需要返回一個繼承自View的視圖即可,真正的顯示任務是交給這個視圖的。因此,我們的ViewFactory類很簡單:

     1public class JavaViewFactory implements ViewFactory
     2{
     3    /*
     4     * (non-Javadoc)
     5     * 
     6     * @see javax.swing.text.ViewFactory#create(javax.swing.text.Element)
     7     */

     8    public View create(Element element)
     9    {
    10        return new JavaEditorView(element);
    11    }

    12}

     

    接下來的重點就是這個JavaEditorView了,所有的語法高亮等顯示功能都是交給它來完成的

    View是一個抽象類,Swing默認給我們提供了多個它的子類,AsyncBoxView, ComponentView, CompositeView, GlyphView, IconView, ImageView, PlainView 以實現對不同文檔類型的顯示,當中只有PlainView是與文本文檔相關的,它實現簡單的多行文本視圖的 View 接口,該文本視圖的文本只有一種字體和顏色,沒錯,我們的JavaEditorView需要繼承自PlainView。

    PlainView提供了很多方法進行文本文檔的視圖顯示,要實現高亮顯示,我們關心的有兩個方法:

    protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1) throws BadLocationException

    一看名字就知道這個方法是控制選中狀態下的顯示方式,由于本文只討論非選中狀態。所以重點看一下另外一個方法:

    protected int drawUnselectedText(Graphics g, int x, int y, int p0, int p1) throws BadLocationException

    這個方法將模型中給定的范圍呈現為正常的未選定文本。使用前景色或指定的顏色顯示文本。

    參數:
    g  - 圖形上下文(做Swing的人再熟悉不過了,文本也是畫出來的)
    x  - 起始 X 坐標,該值 >= 0
    y  - 起始 Y 坐標,該值 >= 0
    p0 - 模型中的起始位置,該值 >= 0
    p1 - 模型中的結束位置,該值 >= 0

    下面是覆蓋后的實現:

    1protected int drawUnselectedText(Graphics g, int x, int y, int startOffset, int endOffset)
    2    throws BadLocationException
    3{
    4    int docLength = getDocument().getLength();
    5    int length = (endOffset < docLength ? endOffset : docLength) - startOffset;
    6
    7    return scanParagraph(g, x, y, startOffset, length);
    8}

    先是得到從起始位置到結束位置的長度,然后再交由scanParagraph去處理指定長度的文本,其實也就是怎么把它畫出來。
    對于一個Java代碼編輯器,要考慮類名,運算符,數字,關鍵字等的顯示方式,所以scanParagraph要做的事情很多,本文只以怎么么高亮顯示類名為例來說明:

     1private int scanParagraph(Graphics g, int x, int y, int startOffset, int length) throws BadLocationException
     2{
     3    Segment seg = new Segment();
     4    //得到編輯器組件
     5    JavaCodeEditor editor = (JavaCodeEditor) getContainer();
     6    //得到startOffset,位置開始的length個長度的字符串,其實也就是我們要處理的字符串
     7    getDocument().getText(startOffset, length, seg);
     8    for (int wordIndex = 0; wordIndex < seg.length();)
     9    {
    10        char currentChar = seg.charAt(wordIndex);
    11        if (Character.isJavaIdentifierStart(currentChar))
    12        {
    13            //下面我默認用Object說明,實際中要處理seg中的內容。
    14            String identifier = "Object";
    15            int len = identifier.length();
    16
    17            //比如說以紅色顯示類名
    18            Segment text = getLineBuffer();
    19            getDocument().getText(startOffset + wordIndex, len, text);
    20            //還有其它樣式的話只管給g加
    21            g.setColor(color);
    22
    23            Utilities.drawTabbedText(text, x, y, g, this, startOffset + wordIndex);
    24            
    25            //下面的代碼略
    26            .
    27        }

    28    }

    29    //下面的代碼略
    30    .
    31}

    我只是以類名進行示范,實際中可能還要考慮此類名是否在注釋當中等等...

    posted on 2010-02-10 14:27 凱子 閱讀(3118) 評論(9)  編輯  收藏 所屬分類: Swing

    評論

    # re: Swing實現Java代碼編輯器 - 語法高亮顯示  回復  更多評論   

    很好
    2010-05-06 11:02 | 匿名

    # re: Swing實現Java代碼編輯器 - 語法高亮顯示  回復  更多評論   

    能把你寫的代碼編輯器發給我學習一下嗎?lysimon@163.com,thanks。
    2010-07-06 21:53 | Simon.C

    # re: Swing實現Java代碼編輯器 - 語法高亮顯示[未登錄]  回復  更多評論   

    為啥米不講仔細一點,比如提拱一下源代碼
    2010-09-18 10:48 | qing

    # re: Swing實現Java代碼編輯器 - 語法高亮顯示  回復  更多評論   

    你好,能否將這個JavaCodeEditor的源碼發給我來全面的學習一下?萬分感謝! waldsteinstay@msn.com
    2010-11-28 09:57 | Waldstein

    # re: Swing實現Java代碼編輯器 - 語法高亮顯示  回復  更多評論   

    能把你寫的代碼編輯器發給我學習一下嗎?964952294@qq.com
    2012-05-03 00:32 | zhu_1989

    # re: Swing實現Java代碼編輯器 - 語法高亮顯示  回復  更多評論   

    能不能發下源代碼?827972471@qq.com
    2012-11-28 22:34 | sunly

    # re: Swing實現Java代碼編輯器 - 語法高亮顯示  回復  更多評論   

    你好!能不能發下源代碼?whboy803@163.com,感謝!
    2013-05-18 18:34 | whboy

    # re: Swing實現Java代碼編輯器 - 語法高亮顯示  回復  更多評論   

    同求源碼
    2015-03-06 16:09 | jycggyh

    # re: Swing實現Java代碼編輯器 - 語法高亮顯示  回復  更多評論   

    非常渴望能夠獲得源代碼,liudsnudt@126.com
    2015-11-24 19:23 | 劉德生

    只有注冊用戶登錄后才能發表評論。


    網站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 特级毛片全部免费播放| 久久精品国产免费观看| a毛片视频免费观看影院| 91在线老王精品免费播放| 国产成人免费a在线视频app| 久久亚洲精品国产精品黑人| 亚洲精华国产精华精华液| 免费在线看黄网站| 91手机看片国产永久免费| 国产亚洲一区二区手机在线观看 | 日韩毛片免费在线观看| 国产亚洲av片在线观看播放| 亚欧乱色国产精品免费视频| 国内精品免费视频自在线| 久久夜色精品国产噜噜噜亚洲AV| 免费国产在线精品一区| 波多野结衣久久高清免费| 亚洲精品午夜久久久伊人| 久久毛片免费看一区二区三区| 巨胸喷奶水视频www网免费| 亚洲精品第一国产综合亚AV| 亚洲AV成人精品日韩一区18p| 亚洲综合色一区二区三区| 69xx免费观看视频| 久久久国产亚洲精品| 1024免费福利永久观看网站| 亚洲欧美日韩一区二区三区在线| 久久久久久精品免费看SSS| 亚洲综合色丁香婷婷六月图片| 国产麻豆免费观看91| 丝袜足液精子免费视频| 亚洲免费日韩无码系列| 黄色一级视频免费观看| 亚洲AV日韩AV永久无码下载| 最近中文字幕mv免费高清电影| 亚洲最新黄色网址| 真人做A免费观看| 男女猛烈无遮掩视频免费软件| 亚洲AV福利天堂一区二区三| 午夜免费福利网站| 免费毛片在线看不用播放器|