Swing應用開發實戰系列之四:組件內容實時刷新問題


 

窗口組件動態刷新問題,在dotnet中根本不算什么問題,用幾句代碼很輕松就能搞定,但是在Swing中,實現動態刷新組件內容卻是一件頗為吃力的事情。譬如針對我們經常用到的刷新JLable、JTextField等組件內容,這些組件本身也提供有諸如updateUI()、validate()以及paintImmediately()等等與界面刷新和組件重繪相關的方法, 但是在常規情況下都不起作用。

 

我們先看個基本的例子,JLabel內容動態刷新的例子,代碼如下。

try {
    for(int i=0;i<5;i++) {
        this.lbInfo.setText(String.format("當前進度:%s", i));
        this.lbInfo.paintImmediately(this.lbInfo.getBounds());
        Thread.sleep(1000);    
    }
} catch (InterruptedException e) {
    e.printStackTrace();
}

我們在一個for循環內每間隔一秒鍾刷新一下Label內容,以期望實現Label內容動態刷新效果,但是並沒有出現我們想象中的效果,Label內容一直保持不變,直到最后才顯示最終的效果,中間的動態內容完全被忽略過去了。這是因為每次調用setText都是運行在主線程中,而且是順序的執行的。在前面幾次調用setText后,線程並沒有退出,所以界面刷新線程不能獲得執行刷新的機會。而當最后一次setText后,線程退出,界面才能執行刷新。所以我們只能看到最后一次setText的值。

 

原來,在Java Swing中,界面刷新是線程同步的,也即是說,在同一時間,只有一個線程能夠執行刷新界面的代碼。如果要多次不斷地刷新界面,必須在多線程中調用刷新的方法。我們將以上的代碼更改為多線程模式,重新運行,結果就完全實現了我們所期望的動態刷新效果。代碼如下。

new Thread(new Runnable(){
    @Override
    public void run() {
        try {
            for(int i=0;i<5;i++) {
                lbInfo.setText(String.format("當前進度:%s", i));
                Thread.sleep(1000);    
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}).start();

那么,除了這種采用顯式多線程模式外,還有沒有其他方法實現內容動態刷新效果呢?我們進行了測試,還真的找到了一種方法,就是結合JScrollPane實現及時動態刷新。在窗體區域創建一個JScrollPane組件,然后將JLabel組件放入JScrollPane中,執行以下代碼,同樣可以實現內容及時動態刷新。代碼如下:

try {
    for(int i=0;i<5;i++) {
        this.lbInfo.setText(String.format("當前進度:%s", i));
        this.lbInfo.paintImmediately(this.lbInfo.getBounds());
        Thread.sleep(1000);    
    }
} catch (InterruptedException e) {
    e.printStackTrace();
}

做一個小小的總結,針對JLableJ、TextField和JTextArea等組件內容的及時動態刷新問題,基本上采用多線程或者JScrollPane方式都可以實現。但是,對於JTextArea組件,如果不采用多線程模式,在內容動態刷新的時候,JTextArea的滾動條將無法與內容區域保持同步。所以最穩妥可靠的做法,就是采用多線程模式實現內容的及時動態刷新。在下一章節中,我們將利用JScrollPane、JTextArea、多線程和Java自定義事件機制,設計實現一個“日志信息前台監控器”,利用前台窗體實時監控顯示后台服務的日志信息。

 

作者:商兵兵

單位:河南省電力科學研究院智能電網所

QQ:52190634

主頁:http://www.cnblogs.com/shangbingbing

空間:http://shangbingbing.qzone.qq.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM