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

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

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

    隨筆 - 4, 文章 - 1, 評(píng)論 - 22, 引用 - 0
    數(shù)據(jù)加載中……

    Swing實(shí)現(xiàn)Java代碼編輯器 - 語(yǔ)法高亮顯示

        本文主要記錄怎么給代碼編輯器實(shí)際語(yǔ)法高亮顯示的功能,先來(lái)張效果圖吧:
        
        

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

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

    EditorKit中有兩個(gè)重要的方法實(shí)現(xiàn)對(duì)文檔的管理與顯示:

    public abstract Document createDefaultDocument();

    創(chuàng)建一個(gè)適合此編輯器類(lèi)型文本存儲(chǔ)模型。EditorKit把對(duì)文本文檔的管理功能交給了這個(gè)方法的返回值。

    public abstract ViewFactory getViewFactory();

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

    因?yàn)槲覀兊木庉嬈骱蚃EditorPane唯一不同的可能就是代碼怎么來(lái)顯示,所以createDefaultDocument()可以返回一個(gè)默認(rèn)的javax.swing.text.DefaultStyledDocument 就行,對(duì)于getViewFactory,我們需要定制一個(gè)ViewFactory視圖來(lái)實(shí)現(xiàn)編輯器獨(dú)有的各種顯示功能。

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

    public View create(Element elem);

    這個(gè)方法根據(jù)給定的文檔的結(jié)構(gòu)化元素創(chuàng)建一個(gè)視圖。在這個(gè)方法中,我們只需要返回一個(gè)繼承自View的視圖即可,真正的顯示任務(wù)是交給這個(gè)視圖的。因此,我們的ViewFactory類(lèi)很簡(jiǎn)單:

     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}

     

    接下來(lái)的重點(diǎn)就是這個(gè)JavaEditorView了,所有的語(yǔ)法高亮等顯示功能都是交給它來(lái)完成的

    View是一個(gè)抽象類(lèi),Swing默認(rèn)給我們提供了多個(gè)它的子類(lèi),AsyncBoxView, ComponentView, CompositeView, GlyphView, IconView, ImageView, PlainView 以實(shí)現(xiàn)對(duì)不同文檔類(lèi)型的顯示,當(dāng)中只有PlainView是與文本文檔相關(guān)的,它實(shí)現(xiàn)簡(jiǎn)單的多行文本視圖的 View 接口,該文本視圖的文本只有一種字體和顏色,沒(méi)錯(cuò),我們的JavaEditorView需要繼承自PlainView。

    PlainView提供了很多方法進(jìn)行文本文檔的視圖顯示,要實(shí)現(xiàn)高亮顯示,我們關(guān)心的有兩個(gè)方法:

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

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

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

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

    參數(shù):
    g  - 圖形上下文(做Swing的人再熟悉不過(guò)了,文本也是畫(huà)出來(lái)的)
    x  - 起始 X 坐標(biāo),該值 >= 0
    y  - 起始 Y 坐標(biāo),該值 >= 0
    p0 - 模型中的起始位置,該值 >= 0
    p1 - 模型中的結(jié)束位置,該值 >= 0

    下面是覆蓋后的實(shí)現(xiàn):

    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}

    先是得到從起始位置到結(jié)束位置的長(zhǎng)度,然后再交由scanParagraph去處理指定長(zhǎng)度的文本,其實(shí)也就是怎么把它畫(huà)出來(lái)。
    對(duì)于一個(gè)Java代碼編輯器,要考慮類(lèi)名,運(yùn)算符,數(shù)字,關(guān)鍵字等的顯示方式,所以scanParagraph要做的事情很多,本文只以怎么么高亮顯示類(lèi)名為例來(lái)說(shuō)明:

     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,位置開(kāi)始的length個(gè)長(zhǎng)度的字符串,其實(shí)也就是我們要處理的字符串
     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            //下面我默認(rèn)用Object說(shuō)明,實(shí)際中要處理seg中的內(nèi)容。
    14            String identifier = "Object";
    15            int len = identifier.length();
    16
    17            //比如說(shuō)以紅色顯示類(lèi)名
    18            Segment text = getLineBuffer();
    19            getDocument().getText(startOffset + wordIndex, len, text);
    20            //還有其它樣式的話(huà)只管給g加
    21            g.setColor(color);
    22
    23            Utilities.drawTabbedText(text, x, y, g, this, startOffset + wordIndex);
    24            
    25            //下面的代碼略
    26            .
    27        }

    28    }

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

    我只是以類(lèi)名進(jìn)行示范,實(shí)際中可能還要考慮此類(lèi)名是否在注釋當(dāng)中等等...

    posted on 2010-02-10 14:27 凱子 閱讀(3121) 評(píng)論(9)  編輯  收藏 所屬分類(lèi): Swing

    評(píng)論

    # re: Swing實(shí)現(xiàn)Java代碼編輯器 - 語(yǔ)法高亮顯示  回復(fù)  更多評(píng)論   

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

    # re: Swing實(shí)現(xiàn)Java代碼編輯器 - 語(yǔ)法高亮顯示  回復(fù)  更多評(píng)論   

    能把你寫(xiě)的代碼編輯器發(fā)給我學(xué)習(xí)一下嗎?lysimon@163.com,thanks。
    2010-07-06 21:53 | Simon.C

    # re: Swing實(shí)現(xiàn)Java代碼編輯器 - 語(yǔ)法高亮顯示[未登錄](méi)  回復(fù)  更多評(píng)論   

    為啥米不講仔細(xì)一點(diǎn),比如提拱一下源代碼
    2010-09-18 10:48 | qing

    # re: Swing實(shí)現(xiàn)Java代碼編輯器 - 語(yǔ)法高亮顯示  回復(fù)  更多評(píng)論   

    你好,能否將這個(gè)JavaCodeEditor的源碼發(fā)給我來(lái)全面的學(xué)習(xí)一下?萬(wàn)分感謝! waldsteinstay@msn.com
    2010-11-28 09:57 | Waldstein

    # re: Swing實(shí)現(xiàn)Java代碼編輯器 - 語(yǔ)法高亮顯示  回復(fù)  更多評(píng)論   

    能把你寫(xiě)的代碼編輯器發(fā)給我學(xué)習(xí)一下嗎?964952294@qq.com
    2012-05-03 00:32 | zhu_1989

    # re: Swing實(shí)現(xiàn)Java代碼編輯器 - 語(yǔ)法高亮顯示  回復(fù)  更多評(píng)論   

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

    # re: Swing實(shí)現(xiàn)Java代碼編輯器 - 語(yǔ)法高亮顯示  回復(fù)  更多評(píng)論   

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

    # re: Swing實(shí)現(xiàn)Java代碼編輯器 - 語(yǔ)法高亮顯示  回復(fù)  更多評(píng)論   

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

    # re: Swing實(shí)現(xiàn)Java代碼編輯器 - 語(yǔ)法高亮顯示  回復(fù)  更多評(píng)論   

    非??释軌颢@得源代碼,liudsnudt@126.com
    2015-11-24 19:23 | 劉德生

    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 国产福利电影一区二区三区,亚洲国模精品一区| 久草免费福利视频| 天天摸天天操免费播放小视频| 18pao国产成视频永久免费| 曰批全过程免费视频观看免费软件| 亚洲精品久久无码| 亚洲高清乱码午夜电影网| 色天使色婷婷在线影院亚洲| 亚洲avav天堂av在线不卡| 亚洲成a人在线看天堂无码| 亚洲国产精品成人久久蜜臀| 亚洲AⅤ优女AV综合久久久| 无码一区二区三区AV免费| 免费毛片在线看片免费丝瓜视频| 成人性生交大片免费看无遮挡 | 亚洲熟女乱色一区二区三区| 学生妹亚洲一区二区| 亚洲五月六月丁香激情| 亚洲精品偷拍无码不卡av| 亚洲丰满熟女一区二区v| 亚洲自偷自偷精品| 亚洲精品日韩中文字幕久久久| 国产精品亚洲自在线播放页码| 亚洲欧美不卡高清在线| 污网站在线观看免费| 一个人看的www免费视频在线观看| 97精品免费视频| 无码国产精品一区二区免费式芒果 | 国产免费看JIZZ视频| 在线观看免费精品国产| 成人午夜性A级毛片免费| 国产免费直播在线观看视频| 热99re久久免费视精品频软件| 免费播放春色aⅴ视频| 又粗又大又猛又爽免费视频| 国产国拍精品亚洲AV片| 亚洲人成网址在线观看| 亚洲日本VA午夜在线电影| 一级女人18片毛片免费视频| 9277手机在线视频观看免费| 免费观看的毛片手机视频|