2014-04-24 52 views
0

我寫了下面的代碼。我沒有顯示完整源代碼,但psudo代碼。無法在java swing中點擊按鈕後立即將按鈕文本更改爲圖標

class UI extends JFrame 
{ 
    //created UI with one Button 
    onButtonclick() 
    { 
     //did some operation before set icon to button 
     //say opened fileopen dialog and get file 
     button.setText(""); 
     ImageIcon progressbar = new  
      ImageIcon(DatasetExporterUI.class.getResource("/progreassbar.gif")); 
      buttonExport.setIcon(progressbar); 

     // did some database operations 
     //again removed icon from button 
     button.setIcon(null); 
     button.setText("click"); 
    } 
} 

當我點擊按鈕它打開文件打開對話框和和按鈕文本設置爲空。 但它沒有設置圖標按鈕。當所有的數據庫操作完成後,圖標設置爲按鈕後執行的時間圖標出現在按鈕上。 爲什麼這是行爲? 如何將圖標設置爲按鈕並執行一些數據庫操作並再次將其刪除? 謝謝。 :)

+0

你有沒有調用'repaint'方法來實現你的改變? – Salah

+0

是的。那也行不通 –

+0

只是在更改按鈕標籤時重新繪製組件 –

回答

3

圖形用戶界面系統只能做一件事的時候,最喜歡的代碼(除了使用線程的代碼)。打電話給你的聽衆是一回事。監聽器運行時,GUI系統無法執行其他任何操作。

您的數據庫操作需要在另一個線程(您可以創建)上運行,然後在完成後更新GUI。類似這樣的:

void onButtonPressed() { 
    // The code to open the file dialog goes here 

    button.setText(""); 
    ImageIcon progressbar = new  
     ImageIcon(DatasetExporterUI.class.getResource("/progreassbar.gif")); 
     buttonExport.setIcon(progressbar); 

    new Thread() { 
     @Override 
     public void run() { 
      // do some database operations here 

      EventQueue.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        //again remove icon from button 
        button.setIcon(null); 
        button.setText("click"); 
       } 
      }); 
     } 
    }.start(); 
} 

不同線程中的代碼同時運行。這很方便但很危險。從新線程訪問數據時要特別小心 - 如果一個線程更改了一個字段而另一個線程讀取了該字段,則結果可能不符合您的預期。最簡單的做法是確保主線程在運行時不會更改新線程使用的任何變量。

當您的數據庫操作完成後,您無法通過調用setText將按鈕設置回正常狀態。只允許主線程影響GUI - 如果主線程在數據庫操作線程正在更改文本的同時在屏幕上繪製按鈕,該怎麼辦?該按鈕可能被錯誤地繪製。所以你需要撥打EventQueue.invokeLater告訴GUI系統在不忙的時候在不久的將來運行你的代碼。 new Runnable() {}中的代碼與按鈕偵聽器中的代碼類似 - 不會運行其他與GUI相關的代碼。

+0

尼斯解答!!! :) –

0

這應該工作:

Image progressbar= ImageIO.read(DatasetExporterUI.class.getResource("/progreassbar.gif")); 

buttonExport.setIcon(new ImageIcon(progressbar));