前言

本文前言部分為我的一些感想,如果你只對(duì)本文介紹的Java實(shí)用技巧感興趣,可以跳過(guò)前言直接看正文的內(nèi)容。

本文的寫(xiě)作動(dòng)機(jī)來(lái)源于最近接給人家?guī)兔?xiě)的一個(gè)小程序,主要用于管理分期付款的貨款的一系列管理,包括過(guò)期款的紀(jì)錄,過(guò)期款利息的計(jì)算,為提前付款的用戶提供一些返款獎(jiǎng)勵(lì)等等,這些與本文無(wú)關(guān)自不必細(xì)說(shuō)。為了盡快完成任務(wù),我自然選擇了我用得最多的Java來(lái)實(shí)現(xiàn)。經(jīng)過(guò)2周的勞動(dòng),順利完成了任務(wù),明天就可以去交差,但是這一刻我卻忽然有些其他的想法。誠(chéng)然這樣的活原本屬于體力勞動(dòng),類似的活我也做過(guò)不止一次,對(duì)于很多高人來(lái)說(shuō),沒(méi)什么值得一提的,以前我也只是交差收錢了事,但這一次我卻多了一些想法,使我不吐不快。

在程序的實(shí)現(xiàn)過(guò)程中,我遇到了個(gè)小問(wèn)題,就是計(jì)算兩個(gè)日期的差。由于以前常用的Date類的大多數(shù)方法都被標(biāo)記為“deprecate”,所以我決定用Calender作為計(jì)算日期的主力。但是大多數(shù)參考書(shū)上都是由關(guān)于Calender的日期格式,Locale的設(shè)置,常量的含義等方面的講解,卻怎么也找不到這樣一個(gè)簡(jiǎn)單卻常用的任務(wù)怎么實(shí)現(xiàn)(注:這也不能怪我懶惰,作為這樣一個(gè)程序來(lái)說(shuō),如果有正確且成熟的方法,誰(shuí)還會(huì)去花大量時(shí)間仔細(xì)研究API呢?反正這個(gè)類可能在今后的幾個(gè)月甚至幾年都用不上,現(xiàn)在記住到時(shí)候也都忘了L)。于是在我google了好一陣之后,終于在某人的Blog上找到了用Calender計(jì)算日期差的方法。在那一刻我真有久旱逢甘雨之感。博主可能是一時(shí)興起,也有可能是興趣所在,但無(wú)論是什么原因,他的工作都為我提供了很大的方便。有了他的代碼示例,我可以不再去逐個(gè)查找Java-Doc里面的API,然后挑出幾個(gè)來(lái)嘗試解決問(wèn)題,最后再寫(xiě)個(gè)demo驗(yàn)證這一繁復(fù)的過(guò)程了。

再回想一下我完成這個(gè)程序的過(guò)程,由于以前做過(guò)一些類似的程序,我可以將里面的很多部分以直接應(yīng)用到這個(gè)程序中,節(jié)省了大量的時(shí)間,讓我可以更專注于核心業(yè)務(wù)的實(shí)現(xiàn)當(dāng)中。然而或許是出于懶惰,或許是沒(méi)有時(shí)間,又或許原來(lái)的是Blog沒(méi)有多少人關(guān)注,我都沒(méi)有將這些大多數(shù)人都可能會(huì)用得上的東西放到網(wǎng)上。

再聯(lián)想一下國(guó)外開(kāi)源工作者對(duì)中國(guó)程序員的評(píng)價(jià)“只獲取,不貢獻(xiàn)”,就覺(jué)得人家說(shuō)得十分對(duì)。自己就用著免費(fèi)的J2SDK語(yǔ)言,免費(fèi)的Eclipse,免費(fèi)的JFreeChart,免費(fèi)的JasperReport……,卻從來(lái)沒(méi)能夠給人家貢獻(xiàn)哪怕一行代碼。這樣也就算了,但是類似于一些力所能及的東西,例如可能每個(gè)Java程序員都會(huì)碰到的一些小問(wèn)題,小技巧,常常出現(xiàn)的錯(cuò)誤,為什么我就不能把他們貼出來(lái)供人分享呢?說(shuō)不定就會(huì)幫到某位哥們解決大問(wèn)題,更有可能你的幾句話就能節(jié)省別人幾分鐘甚至幾小時(shí)的時(shí)間。如果每個(gè)人都能在業(yè)余時(shí)間把自己的一些心得體會(huì)貼出來(lái),相信更多的人將因此受益。當(dāng)你遇到問(wèn)題的時(shí)候,才能心安理得的去GoogleBaidu。相信這也是技術(shù)論壇和技術(shù)Blog的初衷吧,畢竟這個(gè)世界并不是只有錢才是最重要的原動(dòng)力。


1       改變Swing應(yīng)用程序的默認(rèn)字體/字號(hào)

經(jīng)常使用Swing作為程序UI的人可能會(huì)注意到,Swing組件默認(rèn)顯示文字的字號(hào)為11。這對(duì)于英文顯示毫無(wú)問(wèn)題,但是如果用這個(gè)字號(hào)顯示中文的話,這么小的字號(hào)就會(huì)使程序變得很難看。我當(dāng)年在用IReport0.56的時(shí)候就發(fā)現(xiàn)他的菜單欄和彈出的Dialog里的字很難看,但是將字號(hào)調(diào)大之后就好多了。雖然在最近版本的JDK里似乎修正了這個(gè)字體問(wèn)題,但是如果你的程序必須使用以前版本的JDK的話,這個(gè)問(wèn)題就需要處理一下,下面就是一個(gè)不錯(cuò)的解決方案:

Font vFont = new Font("Dialog", Font.PLAIN, 13);

           UIManager.put("ToolTip.font", vFont);

           UIManager.put("Table.font", vFont);

           UIManager.put("TableHeader.font", vFont);

           UIManager.put("TextField.font", vFont);

           UIManager.put("ComboBox.font", vFont);

           UIManager.put("TextField.font", vFont);

           UIManager.put("PasswordField.font", vFont);

           UIManager.put("TextArea.font", vFont);

           UIManager.put("TextPane.font", vFont);

           UIManager.put("EditorPane.font", vFont);

           UIManager.put("FormattedTextField.font", vFont);

           UIManager.put("Button.font", vFont);

           UIManager.put("CheckBox.font", vFont);

           UIManager.put("RadioButton.font", vFont);

           UIManager.put("ToggleButton.font", vFont);

           UIManager.put("ProgressBar.font", vFont);

           UIManager.put("DesktopIcon.font", vFont);

           UIManager.put("TitledBorder.font", vFont);

           UIManager.put("Label.font", vFont);

           UIManager.put("List.font", vFont);

           UIManager.put("TabbedPane.font", vFont);

           UIManager.put("MenuBar.font", vFont);

           UIManager.put("Menu.font", vFont);

           UIManager.put("MenuItem.font", vFont);

           UIManager.put("PopupMenu.font", vFont);

           UIManager.put("CheckBoxMenuItem.font", vFont);

           UIManager.put("RadioButtonMenuItem.font", vFont);

           UIManager.put("Spinner.font", vFont);

           UIManager.put("Tree.font", vFont);

           UIManager.put("ToolBar.font", vFont);

           UIManager.put("OptionPane.messageFont", vFont);

           UIManager.put("OptionPane.buttonFont", vFont);

這段代碼用在程序的開(kāi)始部分,可以有效地將Swing組件的顯示字體設(shè)置為我們?cè)?/span>vFont所設(shè)定的內(nèi)容。

1.1    讓窗口更好地居中顯示

無(wú)論是頂層組件JFrame還是對(duì)話框JDialog,讓他們的窗口居中顯示是一個(gè)很常見(jiàn)的問(wèn)題,因?yàn)樗麄兡J(rèn)總是從左上角彈出來(lái),這也太不爽了!對(duì)于這個(gè)問(wèn)題,JBuilder應(yīng)用程序生成向?qū)Ыo出了解決方案:

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

Dimension frameSize = frame.getSize();

if (frameSize.height > screenSize.height)

    frameSize.height = screenSize.height;       

if (frameSize.width > screenSize.width)

 frameSize.width = screenSize.width;       

frame.setLocation((screenSize.width-frameSize.width)/2,screenSize.height-frameSize.height) / 2);

這個(gè)方法對(duì)于大多數(shù)窗口組件來(lái)說(shuō)都足夠了,但是還有其他問(wèn)題存在,比如說(shuō)分辨率和顯示器的尺寸都會(huì)導(dǎo)致應(yīng)用程序窗口“變形”,明明在17寸顯示器1024*768分辨率下顯示好好的窗口到了19寸的1280*800的寬屏下就會(huì)被“拉”得很“長(zhǎng)”。于是,雖然有布局管理器幫我們管理拉伸后組件的放置,但仍然解決不了拉長(zhǎng)后帶來(lái)的美觀問(wèn)題。我的經(jīng)驗(yàn)是,對(duì)于某些窗口,由于它被“拉長(zhǎng)”之后由于其內(nèi)部組件之間的間隙變大,會(huì)顯得很難看。所以應(yīng)該為他們?cè)O(shè)定一個(gè)最合適的顯示大小。在居中顯示的時(shí)候只調(diào)整位置而不改變大小,這樣就不會(huì)影響窗口的美觀。所以我們只需要對(duì)上面的代碼小改一下即可,以JFrame為例:

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

screenSize = Toolkit.getDefaultToolkit().getScreenSize();

frame.setPreferredSize(new Dimension(512,450));           

int frameWidth = this.getPreferredSize().width;

int frameHeight = this.getPreferredSize().height;

frame.setSize(frameWidth, frameHeight);

frame.setLocation((screenSize.width - frameWidth) / 2,(screenSize.height - frameHeight) / 2);

2       自定義JFrame的關(guān)閉事件

有的時(shí)候,當(dāng)用戶關(guān)閉應(yīng)用程序窗口的時(shí)候,我們可能希望程序在結(jié)束之前保存一些必要的數(shù)據(jù)。對(duì)于這種需求,我們有兩種備選方案:

2.1    獲取程序關(guān)閉的“鉤子”

Runtime.getRuntime().addShutdownHook(shutdownHook);

protected Thread shutdownHook = new PlatformShutdownHook();   

    protected class PlatformShutdownHook extends Thread {

        public void run()

        {

            //一些清理工作在這里進(jìn)行……

        }

}

通過(guò)這種方法,我們就可以在程序結(jié)束時(shí)獲得通知,以便進(jìn)行一些保存或清理的工作。然而這種方法的缺點(diǎn)是,在程序收到結(jié)束通知的時(shí)候,所有的UI組件已經(jīng)被銷毀了,用戶此時(shí)看到的是程序已經(jīng)結(jié)束。而事實(shí)上如果程序保存需要花很長(zhǎng)的時(shí)間的話,用戶是不能獲取任何信息的,這是一個(gè)很糟糕的用戶體驗(yàn)。因?yàn)槿绻@時(shí)用戶關(guān)機(jī)的話,程序就有可能丟失尚未保存的信息,而對(duì)于這一切,用戶并不知情。

2.2    處理JFrame關(guān)閉事件

為了在UI被銷毀之前收到程序結(jié)束的消息,我們需要自行處理窗口關(guān)閉的事件。注意在這里我們沒(méi)有采用addActionListener(……)方法,因?yàn)檫@樣做只能讓我們?cè)诖翱陉P(guān)閉之后收到通知,這樣就與上面的方法沒(méi)什么區(qū)別了。

我們需要在JFrame的構(gòu)造函數(shù)中設(shè)置:

//設(shè)定標(biāo)志,讓MainFrame自己接收窗口事件

enableEvents(AWTEvent.WINDOW_EVENT_MASK);

然后再實(shí)現(xiàn)下面的函數(shù):

protected void processWindowEvent(final WindowEvent pEvent) {

        if (pEvent.getID() == WindowEvent.WINDOW_CLOSING) {

            /** 防止用戶多次點(diǎn)擊關(guān)閉按鈕造成重復(fù)保存 **/

            if( !isClosing ) isClosing = true;

            else return;

 

            //處理JFrame關(guān)閉事件……

        }else{

            //忽略其他事件,交給JFrame處理

            super.processWindowEvent(pEvent);

        }

}

如此一來(lái),我們就可以在窗口被關(guān)閉之前通知用戶程序正在保存數(shù)據(jù)的信息,例如后面提到的InfiniteProgressPanel可以顯示的內(nèi)容。

3       日期選擇組件與JDialog的沖突問(wèn)題

由于很多應(yīng)用程序都需要用戶輸入日期,卻又怕用戶輸入的日期格式錯(cuò)誤,所以日期選擇組件便應(yīng)運(yùn)而生。雖然我們很需要它,但是網(wǎng)上絕大多數(shù)的組件都是需要給錢的。在找到SwingX之前,我找到的唯一能夠免費(fèi)使用的日歷組件就是一個(gè)名為DateChooserJDialog

看樣子很不錯(cuò),它支持中文,對(duì)于今天高亮顯示,可以調(diào)整年分和月份……一切都非常符合要求。但是這么好的組件卻不能用在我的程序里,原因是在我的程序中,調(diào)用這個(gè)組件的組件也是一個(gè)JDialog,并且設(shè)置了setAlwaysOnTop(true)—即總在最前端顯示。由于DateChooser也設(shè)定了在最前端顯示,這就導(dǎo)致了它和其父組件的顯示沖突,最終結(jié)果是DateChooser不能正常顯示。對(duì)于這個(gè)問(wèn)題,我最終使用SwingX的組件DatePicker來(lái)代替DateChooser完成選擇日期的使命,慣于DatePicker的使用我將來(lái)會(huì)在“SwingX使用詳解”中提到,這里就不再細(xì)說(shuō)。但是這個(gè)問(wèn)題仍然值得我們注意,即如果一個(gè)窗口組件是設(shè)置了總在最前端顯示的JDialog,那么就不要以這個(gè)JDialog為父組件來(lái)彈出其他JDialog,以避免沖突的發(fā)生。

4       JTable的實(shí)用技巧

無(wú)論對(duì)于什么樣的一個(gè)應(yīng)用程序來(lái)說(shuō),用表格的形式來(lái)顯示數(shù)據(jù)是再平常不過(guò)的事情了。于是JTable就成為我們?cè)谒?/span>Swing組件中最不可或缺的朋友。對(duì)于JTable的操作,大多數(shù)情況下我們都可以不假外求,因?yàn)?/span>JDK自帶的例子SwingSet2給我們展示了足夠多的功能。

在這個(gè)例子里,我們可以改變單元格的間距,行高,選擇類型(Selection Style),是否顯示水平線,甚至可以將表格內(nèi)容打印出來(lái)。其中,表格除了文字之外還可以包含其他組件和內(nèi)容,如SwingSet2種就加入了可以選擇顏色的JComboBox和喜愛(ài)的食物所代表的圖片。

但有些時(shí)候,我們還會(huì)有一些其他的需求。例如說(shuō)為了保護(hù)我們的眼睛,我們希望表格的內(nèi)容是帶有間隔色的,如奇數(shù)行顯示藍(lán)色,而偶數(shù)行顯示白色。又或者我們希望表格中某些列的內(nèi)容是可編輯的,而且他列的內(nèi)容是不可編輯的。又或者讓表格中的列帶有排序的功能,能讓我們點(diǎn)一下表頭它就自己按照從低到高或從高到低的順序自行排列。最后我們希望表格的表頭和單元格力的內(nèi)容能夠居中顯示。讓我們一個(gè)一個(gè)來(lái)實(shí)現(xiàn)這些功能!

4.1    間隔色表格及單元格/表頭居中顯示

JTableAPI并沒(méi)有為我們提供更改表格行或列的顏色的能力。但是我們知道,表格的表頭和內(nèi)容的呈現(xiàn)形式都是由相應(yīng)的Renderer來(lái)控制的,所以我們只需要繼承單元格默認(rèn)的Renderer并作相應(yīng)的修改就可以達(dá)到目的:

由于實(shí)現(xiàn)了接口TableCellRenderer,我們只需要實(shí)現(xiàn)唯一的函數(shù)getTableCellRendererComponent(…)。在上例中我們看到,在函數(shù)中我們判斷當(dāng)前行是奇數(shù)還是偶數(shù),如果是奇數(shù),就設(shè)置其背景色為淡藍(lán)色,否則就設(shè)其背景色為白色。在每次更新表格內(nèi)容的時(shí)候,我們只需要調(diào)用下面的函數(shù),就可以保證表格在內(nèi)容被更改之后依然正確顯示間隔色。

/** 為所有表格設(shè)置間隔色 **/

    private void setRenderColor(){

for( int i = 0; i < table.getColumnModel().getColumnCount(); i++ )                   table.getColumn( colname[i] ).setCellRenderer(colorRender );       

}

另外,如果我們想要讓單元格中的內(nèi)容居中顯示的話,請(qǐng)注意到在設(shè)置間隔色部分下面的函數(shù),通過(guò)setHorizontalAlignment(SwingConstants.CENTER)我們就可以讓單元格內(nèi)容居中顯示。

雖然JTable表格的表頭在默認(rèn)情況下應(yīng)該是居中顯示的,但不知道為什么,在我的應(yīng)用程序中表格的表頭總是左對(duì)齊顯示,這讓我惱火不已。由于和單元格一樣,表頭的各項(xiàng)顯示指標(biāo)也是由其Renderer控制的,所以只需要設(shè)置一下表頭的Renderer就能達(dá)到目的:

DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer();

renderer.setHorizontalAlignment(renderer.CENTER);

利用這種方法,如果我們需要讓他右對(duì)齊似乎也不是什么難事,對(duì)嗎?

4.2    讓某些單元格不可編輯

有些時(shí)候,我們希望有些行/列可以被編輯,而有些行/列不能被編輯。如下就是一例,我的程序希望第一列(編號(hào)列)的內(nèi)容可以被用戶通過(guò)雙擊進(jìn)行編輯,而其他列則不能被用戶編輯。單元格能否被編輯取決于JTableisCellEditable(int row,int column)。如果該函數(shù)返回true(row,column)所代表的單元格可以被編輯,否則該單元格不能被編輯。于是我建立了一個(gè)名為SingleUnitEditableTable的類,他繼承自JTable,并OverwriteisCellEditable(int row,int column)方法:

//設(shè)置單元格不可編輯,為缺省實(shí)現(xiàn)

    public boolean isCellEditable(int row, int column) {

        if( editableColumn != -1){

            if( column == editableColumn )

                return true;

            return false;

        }

        return false;

}

其中的editableColumn是一個(gè)內(nèi)部屬性,用來(lái)指定哪個(gè)列可以被編輯。通過(guò)這個(gè)例子,我相信,如果你想實(shí)現(xiàn)奇數(shù)行/列可編輯而偶數(shù)行/列不可被編輯或者滿足特定條件的單元格不可被編輯這樣的JTable易如反掌了吧?下面就是我的應(yīng)用程序的結(jié)果:

第一列可編輯

其他列均不可編輯

4.3    JTable自排序

這個(gè)問(wèn)題已經(jīng)由JDK6.0幫我們解決了,在這個(gè)版本,JDK為我們提供了一個(gè)名為TableRowSorter的類,在程序中我們只需要寫(xiě)2行代碼即可實(shí)現(xiàn)表格內(nèi)容的排序:

TableRowSorter sorter = new TableRowSorter(tableModel);

       accAllTable.setRowSorter(sorter);

看到“編號(hào)”列旁邊的箭頭了嗎?如果我們用鼠標(biāo)點(diǎn)擊表頭,JTable就會(huì)自動(dòng)為我們由小到大排序,再點(diǎn)一下,表格就會(huì)從大到小排序,真是十分方便。而對(duì)于JDK6.0之前的應(yīng)用程序就沒(méi)有這么好的運(yùn)氣了,我們需要自己實(shí)現(xiàn)一個(gè)TableRowSorter,并且自己生成一個(gè)表頭的Renderer來(lái)實(shí)現(xiàn)排序小箭頭,真是繁瑣啊!我這里倒是有一個(gè)不錯(cuò)的實(shí)現(xiàn),如果有人需要的話可以給我留言。不過(guò)自己實(shí)現(xiàn)Renderer采用的是JLabel,會(huì)改變表頭的模樣,不如默認(rèn)的表頭好看,所以可能的話還是升級(jí)吧J

5       JEditorPane顯示HTML描述的文本

JDK1.4開(kāi)始,Swing的很多組件(如JLabel)都可以顯示HTML語(yǔ)言寫(xiě)的文本。這是一個(gè)巨大的進(jìn)步,因?yàn)槲覀兛梢詫⑺@示的文字的配置信息如字體,字號(hào),顏色,換行等信息直接以HTML寫(xiě)入到組件的setText()方法當(dāng)中,不但免去了事后對(duì)這些信息進(jìn)行繁雜配置的煩惱,而且還豐富和簡(jiǎn)化了所要顯示文本的形式。而JEditorPane則有所不同,它天生就是用來(lái)分析并顯示格式化文本的,由一些Java寫(xiě)的開(kāi)源Web瀏覽器甚至都采用改進(jìn)后的JEditorPane作為Web頁(yè)的顯示器。下圖就是SwingSet2中的JEditorPane相關(guān)的例子。我們可以看到JEditorPane可以顯示大多數(shù)的HTML元素,包括圖片,格式化文字,URL鏈接等。

然而通過(guò)JEditorPane顯示HTML描述的文本有兩種方式:

第一種是直接使用JEditorPane.setPage(String htmlTxt);來(lái)顯示用html語(yǔ)言寫(xiě)成的文本。但是這種方法的缺點(diǎn)是無(wú)法顯示HTML文本中所描述的對(duì)外部資源(如圖片,CSS等)的引用。所以如果要顯示更為豐富的信息,僅僅用第一種方法是不夠的。

       所以第二種方法就呼之欲出:將用HTML語(yǔ)言描述的動(dòng)態(tài)文本信息寫(xiě)到文件中,使之成為真正的HTML文件,再用JEditorPane.setPage(URL)JEditorPane.setPage(String htmlFilePath)JEditorPane方法讀入這個(gè)動(dòng)態(tài)生成的內(nèi)容文件就可以讓JEditorPane自動(dòng)為我們顯示豐富的信息了。

   String vNewReportFileName = "file:///c:/temp.html";

   JEditorPane reportPane = new JEditorPane();

   File f = new File(FileUtil.reportDir,vNewReportFileName);

 FileWriter fw = new FileWriter(f, false);

   fw.write("<html>");

 fw.write("<head>");

 …………

  fw.write("</body></html>");

//清理操作

  fw.flush();

  fw.close();

  f = null;

reportPane.setPage(vNewReportFileName);

下圖就是我的程序所顯示的結(jié)果,從圖中我們可以清楚地看到由CSS文件定義的表格的Title,這個(gè)Title是由一個(gè)藍(lán)色的圖片作為背景的。

讓人遺憾的是用JEditorPane顯示的表格的邊框都很粗,雖然我已經(jīng)將了表格的border設(shè)置為1,可是JEditorPane依然我行我素。但是在IE下,表格的邊框的表現(xiàn)就要好的多:

網(wǎng)上有人說(shuō)這是一個(gè)Bug,但是沒(méi)有人給過(guò)解決這個(gè)問(wèn)題的方法,如果有人又解決方法的話請(qǐng)留言,我將不勝感激!

6       InfiniteProgressPanel實(shí)現(xiàn)GlassPane

俗話說(shuō)重要人物都最后出場(chǎng),作為Swing篇的完結(jié)部分,我為大家隆重推薦一個(gè)GlassPane的實(shí)現(xiàn)—InfiniteProgressPanel,它的效果如圖所示:

怎么樣,很酷吧?這是在程序進(jìn)行更新的時(shí)候能夠給用戶以提示,可以屏蔽用戶操作而且十分美觀的特殊進(jìn)度條。它源于一個(gè)超級(jí)Java大牛的手筆,此君的《Swing Hacker》在去年如帶給我的震撼到現(xiàn)在還揮之不去。從那以后,誰(shuí)再敢說(shuō)Java不能做出好看的用戶界面之前都需要自己好好掂量一下自己是否有這么說(shuō)的資格。這本書(shū)讓我真正認(rèn)識(shí)到,只有想不到?jīng)]有做不到。都是一樣用Swing,為啥人家就能玩出花樣呢?差距!

其實(shí)現(xiàn)原理很簡(jiǎn)單,說(shuō)白了就是用Java2D畫(huà)圈!至于源碼各位可以到網(wǎng)上自己搜。他的使用十分簡(jiǎn)單:

InfiniteProgressPanel glassPane = new InfiniteProgressPanel();

frame.setGlassPane(glassPane)

在需要它顯示的時(shí)候,就這樣做:

 Thread myThread = new Thread(new Runnable(){

         public void run() {

              InfiniteProgressPanel gl = thisRef.glassPane;

              gl.start();

              gl.setText("正在保存數(shù)據(jù)請(qǐng)稍候....");

              try {

                 //這里放要做的事情……

                 gl.setText("保存完畢,歡迎使用!");

                 Thread.sleep(1000);

               }catch(InterruptedException ex) {

               }finally{

                 gl.stop();

               }

            }

    });

myThread.start();       

這里有幾個(gè)問(wèn)題需要注意:

1.         必須要將InfiniteProgressPanel的顯示放到一個(gè)線程里,相信大家都知道原因,我不用多說(shuō)。

2.         InfiniteProgressPanel結(jié)束之前的Thread.sleep(1000);是必要的,如果時(shí)間設(shè)得太短或不設(shè)將會(huì)導(dǎo)致InfiniteProgressPanel死掉。至于原因我沒(méi)有時(shí)間深究,各位有興趣可以自行察看其源碼,如果你能找到原因高訴我,我會(huì)非常感激。

3.         在有些時(shí)候會(huì)出現(xiàn)圓圈“四處亂竄”的現(xiàn)象,不過(guò)不太常見(jiàn)。