當(dāng)柳上原的風(fēng)吹向天際的時(shí)候...

          真正的快樂來源于創(chuàng)造

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
          注:以下是Swing GUI處理的一個(gè)小小技巧,對此無興趣者請退散。

          在Swing中有這樣一種狀況:即長時(shí)間運(yùn)行的事件回調(diào),當(dāng)它運(yùn)行時(shí),其余的GUI是沒有響應(yīng)的。如果這會持續(xù)較長的一段時(shí)間,它可能會讓使用者感到挫折和困惑。下面一段程序就展示了這一現(xiàn)象,其粗體部分的本意是每隔一秒刷新標(biāo)簽中的文字,但是結(jié)果是按鈕事件響應(yīng)完畢后,標(biāo)簽上顯示最后一段文字:
          package com.heyang;

          import java.awt.BorderLayout;
          import java.awt.Dimension;
          import java.awt.Toolkit;
          import java.awt.event.ActionEvent;
          import java.awt.event.ActionListener;

          import javax.swing.JButton;
          import javax.swing.JFrame;
          import javax.swing.JLabel;

          public class MyFrame extends JFrame{
              
          private static final long serialVersionUID = -5100794608937579830L;
              
              
          private JLabel msgLbl;
              
          private JButton cmdBtn;
              
              
          public MyFrame(){
                  setTitle(
          "MyFrame");
                  
                  msgLbl
          =new JLabel("提示文字");
                  cmdBtn
          =new JButton("刷新文本");
                  
                  
          this.setLayout(new BorderLayout());
                  
          this.add(msgLbl,BorderLayout.NORTH);
                  
          this.add(cmdBtn,BorderLayout.CENTER);
                  
                  
          // 設(shè)置大小,位置
                  setSizeAndCentralizeMe(300200);
                  
                  
          // 點(diǎn)擊窗口右上角的關(guān)閉按鈕關(guān)閉窗口,直接退出程序
                  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  
                  
          // 按鈕事件注冊
                  cmdBtn.addActionListener(new ActionListener() {
                      
          public void actionPerformed(ActionEvent e) {
                          runCmd();
                      }
                  });
                  
                  setVisible(
          true);
              }
              
              
          private void runCmd(){
                  msgLbl.setText(
          "溫故而知新,可以為師矣。");
                  longTimeProcess(
          10);
                  
                  msgLbl.setText(
          "由,汝知之乎!知之為知之,不知為不知,是知也。");
                  longTimeProcess(
          10);
                  
                  msgLbl.setText(
          "見賢思齊焉,見不賢而內(nèi)自省也");
                  longTimeProcess(
          10);
                  
                  msgLbl.setText(
          "士不可以不弘毅,任重而道遠(yuǎn)。");
                  longTimeProcess(
          10);
                  
                  msgLbl.setText(
          "歲寒,然后知松柏之后凋也。");
                  longTimeProcess(
          10
          );
              }
              
              
          /**
               * 模擬一個(gè)長時(shí)處理,以100毫秒為單位
               * 
               * 說明:
               * 
          @param mSeconds
               * 創(chuàng)建時(shí)間:2011-1-9 下午12:02:28
               
          */
              
          private void longTimeProcess(int mSeconds){
                  
          try{
                      Thread.sleep(mSeconds
          *100);
                  }
                  
          catch(Exception e){
                      
                  }
              }
              
              
          private void setSizeAndCentralizeMe(int width, int height) {
                  Dimension screenSize 
          = Toolkit.getDefaultToolkit().getScreenSize();
                  
          this.setSize(width, height);
                  
          this.setLocation(screenSize.width / 2 - width / 2, screenSize.height
                          
          / 2 - height / 2);
              }
              
              
          public static void main(String[] args){
                  
          new MyFrame();
              }
          }

          要達(dá)到預(yù)期的效果,Swing建議:讓長時(shí)間運(yùn)行的任務(wù)在獨(dú)立的線程中運(yùn)行會好很多,這樣能夠讓GUI有適當(dāng)響應(yīng)。修改后的代碼如下:
          package com.heyang;

          import java.awt.BorderLayout;
          import java.awt.Dimension;
          import java.awt.Toolkit;
          import java.awt.event.ActionEvent;
          import java.awt.event.ActionListener;

          import javax.swing.JButton;
          import javax.swing.JFrame;
          import javax.swing.JLabel;

          public class MyFrame extends JFrame{
              
          private static final long serialVersionUID = -5100794608937579830L;
              
              
          private JLabel msgLbl;
              
          private JButton cmdBtn;
              
              
          public MyFrame(){
                  setTitle(
          "MyFrame");
                  
                  msgLbl
          =new JLabel("提示文字");
                  cmdBtn
          =new JButton("刷新文本");
                  
                  
          this.setLayout(new BorderLayout());
                  
          this.add(msgLbl,BorderLayout.NORTH);
                  
          this.add(cmdBtn,BorderLayout.CENTER);
                  
                  
          // 設(shè)置大小,位置
                  setSizeAndCentralizeMe(300200);
                  
                  
          // 點(diǎn)擊窗口右上角的關(guān)閉按鈕關(guān)閉窗口,直接退出程序
                  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  
                  
          // 按鈕事件注冊
                  cmdBtn.addActionListener(new ActionListener() {
                      
          public void actionPerformed(ActionEvent e) {
                          runCmd();
                      }
                  });
                  
                  setVisible(
          true);
              }
              
              
          private void runCmd(){
                  new Thread(){
                      
          public void
           run(){
                          msgLbl.setText(
          "溫故而知新,可以為師矣。");
                          longTimeProcess(
          10);
                          
                          msgLbl.setText(
          "由,汝知之乎!知之為知之,不知為不知,是知也。");
                          longTimeProcess(
          10);
                          
                          msgLbl.setText(
          "見賢思齊焉,見不賢而內(nèi)自省也");
                          longTimeProcess(
          10);
                          
                          msgLbl.setText(
          "士不可以不弘毅,任重而道遠(yuǎn)。");
                          longTimeProcess(
          10);
                          
                          msgLbl.setText(
          "歲寒,然后知松柏之后凋也。");
                          longTimeProcess(
          10);
                      }
                  }.start();

              }
              
              
          /**
               * 模擬一個(gè)長時(shí)處理,以100毫秒為單位
               * 
               * 說明:
               * 
          @param mSeconds
               * 創(chuàng)建時(shí)間:2011-1-9 下午12:02:28
               
          */
              
          private void longTimeProcess(int mSeconds){
                  
          try{
                      Thread.sleep(mSeconds
          *100);
                  }
                  
          catch(Exception e){
                      
                  }
              }
              
              
          private void setSizeAndCentralizeMe(int width, int height) {
                  Dimension screenSize 
          = Toolkit.getDefaultToolkit().getScreenSize();
                  
          this.setSize(width, height);
                  
          this.setLocation(screenSize.width / 2 - width / 2, screenSize.height
                          
          / 2 - height / 2);
              }
              
              
          public static void main(String[] args){
                  
          new MyFrame();
              }
          }

          以上代碼達(dá)到了預(yù)期效果,其中起關(guān)鍵作用的代碼就是以上粗體部分,它將長時(shí)處理放到了另一個(gè)線程中運(yùn)行。
          這種做法不是唯一解決之道,Sun提供的SwingWorker類可以幫你達(dá)到目的,只是要繁瑣一些。這樣的技巧在耗時(shí)檢查,與服務(wù)器交互和復(fù)雜圖形處理中都能有所應(yīng)用。

          參考書籍:
          O'REILLY 《Java 線程》一書。

          最后感謝您看到這里。

          何楊,2011年1月9日14:20:37


          posted on 2011-01-09 14:08 何楊 閱讀(1056) 評論(3)  編輯  收藏

          Feedback

          # re: Swing中長時(shí)間運(yùn)行的事件回調(diào)里進(jìn)行界面刷新的特殊處理 2011-12-02 15:32 iridiumcao
          runCmd 方法中的線程更新了GUI組件,不是妥否?

          這幾天我也被同樣的問題困擾。  回復(fù)  更多評論
            

          # re: Swing中長時(shí)間運(yùn)行的事件回調(diào)里進(jìn)行界面刷新的特殊處理 2011-12-09 15:47 何楊
          @iridiumcao

          界面沒出問題就行。  回復(fù)  更多評論
            

          # re: Swing中長時(shí)間運(yùn)行的事件回調(diào)里進(jìn)行界面刷新的特殊處理 2012-01-02 20:13 iridiumcao
          @何楊
          O(∩_∩)O謝謝  回復(fù)  更多評論
            


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 全州县| 南昌市| 泸水县| 司法| 江北区| 满城县| 怀来县| 怀柔区| 乌恰县| 东阳市| 长治市| 自贡市| 红桥区| 凉山| 平顶山市| 龙泉市| 昂仁县| 东乌珠穆沁旗| 溆浦县| 寿阳县| 准格尔旗| 禄丰县| 古交市| 健康| 灵丘县| 大同县| 长武县| 吴川市| 眉山市| 淮南市| 东城区| 营山县| 陈巴尔虎旗| 濉溪县| 香格里拉县| 兴国县| 甘肃省| 绥化市| 确山县| 班戈县| 台南市|