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

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

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

    silvermyth

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      1 隨筆 :: 12 文章 :: 1 評論 :: 0 Trackbacks
        在開發Java Swing應用程序的過程中,有兩個原則是必須要牢記的:
        1.耗時的操作(例如從數據庫查詢大量數據,讀取URI資源等)一定不能運行在EDT(事件派發線程)上,否則會導致Swing用戶界面失去響應。
        2.只能在EDT線程上對Swing Components進行訪問。
        基于上面兩點原因,在一個Java Swing程序中,要想使用戶界面響應靈敏,至少應該有兩個線程;一個線程用來執行耗時操作,EDT線程用來執行所有與Swing Components的交互,例如更新文本,重繪圖形等等。這就要求兩個線程之間要相互通訊,給程序的開發帶來了不少的難度,Swing Worker的出現從根本上解決了這個問題,使程序員快速開發反應靈敏的的Swing程序成為可能。SwingWoker被設計應用在此種場景下,你有一個耗時操作需要運行在后臺,在該操作完成或部分完成時,你要利用操作返回的結果去更新用戶界面。
        讓我們假想有這樣一個應用場景,我有一個保存聯系人的文件,我需要從中讀取并解析出所有聯系人的信息,并及時更新在一個JTable中;假設這個文件非常的大,解析出所有聯系人的信息需要花費幾分鐘的時間,如果不能很好的協調這個任務和EDT線程,則很有可能會造成用戶在幾分鐘時間里得不到結果,而Swing界面處于無響應狀態。在這種情況下,SwingWorker就是一個絕佳的選擇。我們首先看一下SwingWorker的定義:
        public abstract class SwingWorker<T,V> extends Object implements RunnableFuture<T>
    顯然,這時一個抽象的模板類,在應用的時候,我們需要繼承SwingWorker并實例化模板參數。那么,這兩個模板類型究竟是什么意思呢,T參數代表的是你的耗時任務執行完成時返回的結果類型,V代表的是你的耗時任務部分完成時返回的結果類型。在我們的場景中,假設任務完成時我們需要一個List<BeanContact>(BeanContact是一個保存聯系人信息的JavaBean),每當從文件中解析出一個聯系人信息時,我們會新建一個BeanContact并需要更新到JTable中。那么我們的T就是List<BeanContact>,而V就是BeanContact,則應該定義如下的類:
         public class LoadContactsTask extends SwingWorker<List<BeanContact>, BeanContact> {
                

         @Override
        protected List<BeanContact> doInBackground() throws Exception {

            //To do the task and return the result
        }


         }
        從上面可以看到,我們還必須覆蓋SwingWorker的doInBackground方法,該方法執行我們的耗時操作,并且返回模板實例化時的T類型結果。下面是具體的代碼實現:
         

        @Override
        protected List<BeanContact> doInBackground() throws Exception {
            BufferedReader reader = new BufferedReader(new FileReader("c:/contacts.cff"));
            String line = null;
            while ((line = reader.readLine()) != null) {
                String[] strContacts = line.split(",");
                BeanContact contact = new BeanContact();
                contact.setName(strContacts[0]);
                contact.setSex(strContacts[1]);
                contact.setPhone(strContacts[2]);
                contact.setEmail(strContacts[3]);

                lineCnt++;
                publish(contact);/*********/
               contacts.add(contact);
               
                Thread.sleep(100);
            }
            return contacts;
        }

         該方法很簡單,就是從文件中讀取一個聯系人的記錄并且新建一個BeanContact實例添加到結果集中。我們需要注意的是其中的publish方法,該方法用來發布部分執行結果,每讀取一個聯系人信息,我們就用該方法把新建的BeanContact發布出去。我們需要知道的是,在publish若干個結果后(可能是一個或多個,由SwingWorker類實現)SwingWorker類的process方法會被自動回調,而我們可以在其中去更新用戶界面,SwingWorker保證process方法中所有操作都運行在EDT線程中。下面是我們的具體實現:
        @Override
        protected void process(List<BeanContact> chunks) {
            if (progressHandle != null) {
                progressHandle.processInProgress(chunks, lineCnt * 100 / 10000);
            }
        }

        我們的實現中,process中會調用IProgressHandle(自定義的一個接口,用來更新用戶界面,詳見后面代碼)的processInProgress方法來更新用戶界面,大家會注意到process方法的參數是一個List<BeanContact>,為什么不是一個BeanContact呢,答案就是我們在上面講過的,有可能publish若干次后才調用process方法。
        與此類似,在doInBackground完成后,SwingWorker會自動調用done方法,下面是我們的實現:
        @Override
        protected void done() {
            if (progressHandle != null) {
                progressHandle.processComplete(contacts);
            }
        }
        客戶端如何來使用用SwingWork呢,很簡單,只需要新建一個實例并且調用它的execute方法即可,他會自動調用doInBackground方法來完成操作;以下是完整的代碼實現:
        
        

    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package swingworkertest;

    /**
     *
     * @author Administrator
     */
    public class BeanContact {
        private String name=null;
        private String sex=null;
        private String phone=null;
        private String email=null;

        /**
         * @return the name
         */
        public String getName() {
            return name;
        }

        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }

        /**
         * @return the sex
         */
        public String getSex() {
            return sex;
        }

        /**
         * @param sex the sex to set
         */
        public void setSex(String sex) {
            this.sex = sex;
        }

        /**
         * @return the phone
         */
        public String getPhone() {
            return phone;
        }

        /**
         * @param phone the phone to set
         */
        public void setPhone(String phone) {
            this.phone = phone;
        }

        /**
         * @return the email
         */
        public String getEmail() {
            return email;
        }

        /**
         * @param email the email to set
         */
        public void setEmail(String email) {
            this.email = email;
        }
       
    }


    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */

    /*
     * Contacts.java
     *
     * Created on 2011-6-25, 10:40:13
     */
    package swingworkertest;

    import javax.swing.JFileChooser;

    /**
     *
     * @author Administrator
     */
    public class Contacts extends javax.swing.JFrame {

        /** Creates new form Contacts */
        public Contacts() {
            initComponents();
            handle = new DefaultProgressHandle();
            handle.setTable(jTable1);
            handle.setProgressBar(jProgressBar1);
        }

        /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
        private void initComponents() {

            jButton1 = new javax.swing.JButton();
            jTextField1 = new javax.swing.JTextField();
            jScrollPane1 = new javax.swing.JScrollPane();
            jTable1 = new javax.swing.JTable();
            jButton2 = new javax.swing.JButton();
            jProgressBar1 = new javax.swing.JProgressBar();

            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

            jButton1.setText("瀏覽");
            jButton1.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton1ActionPerformed(evt);
                }
            });

            jTextField1.setEditable(false);

            jTable1.setModel(new javax.swing.table.DefaultTableModel(
                new Object [][] {

                },
                new String [] {
                    "姓名", "性別", "電話", "電子郵件"
                }
            ) {
                Class[] types = new Class [] {
                    java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
                };

                public Class getColumnClass(int columnIndex) {
                    return types [columnIndex];
                }
            });
            jScrollPane1.setViewportView(jTable1);

            jButton2.setText("加載聯系人");
            jButton2.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton2ActionPerformed(evt);
                }
            });

            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 557, Short.MAX_VALUE)
                        .addComponent(jProgressBar1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 557, Short.MAX_VALUE)
                        .addComponent(jButton2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 557, Short.MAX_VALUE)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 97, Short.MAX_VALUE)
                            .addGap(18, 18, 18)
                            .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 442, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addContainerGap())
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jButton1)
                        .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(jButton2)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            );

            layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jButton1, jButton2, jTextField1});

            pack();
        }// </editor-fold>                       

        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                        

            ContactsFileFilter filter = new ContactsFileFilter();
           
            JFileChooser chooser = new JFileChooser();
            chooser.setFileFilter(filter);
            int returnVal = chooser.showOpenDialog(null);
            if(returnVal == JFileChooser.APPROVE_OPTION){
                jTextField1.setText(chooser.getSelectedFile().getAbsolutePath());
            }
        }                                       

        private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                        
            // TODO add your handling code here:
            LoadContactsTask task = new LoadContactsTask(jTextField1.getText());
            task.setProgressHandle(handle);
            task.execute();
        }                                       

        /**
         * @param args the command line arguments
         */
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {

                public void run() {
                    Contacts contacts = new Contacts();
                    contacts.setTitle("Contacts");;
                    contacts.setVisible(true);
                }
            });
        }
        DefaultProgressHandle handle = null;
        // Variables declaration - do not modify                    
        private javax.swing.JButton jButton1;
        private javax.swing.JButton jButton2;
        private javax.swing.JProgressBar jProgressBar1;
        private javax.swing.JScrollPane jScrollPane1;
        private javax.swing.JTable jTable1;
        private javax.swing.JTextField jTextField1;
        // End of variables declaration                  
    }


    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package swingworkertest;

    import java.io.File;
    import javax.swing.filechooser.FileFilter;

    /**
     *
     * @author Administrator
     */
    public class ContactsFileFilter extends FileFilter{

        public boolean accept(File pathname) {
            if(pathname.isDirectory()){
                return true;
            }else{
                return pathname.getName().endsWith(".cff");
            }
        }

        @Override
        public String getDescription() {
            return "Text Files";
        }
       
    }


    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package swingworkertest;

    import java.util.List;
    import javax.swing.JProgressBar;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableModel;

    /**
     *
     * @author Administrator
     */
    public class DefaultProgressHandle implements IProgressHandle {

        private JTable table = null;
        private JProgressBar progressBar = null;

        public void processInProgress(List<BeanContact> contacts, int progress) {
            DefaultTableModel model = (DefaultTableModel) table.getModel();
            for (BeanContact contact : contacts) {
                String[] strArray = {contact.getName(), contact.getSex(), contact.getPhone(), contact.getEmail()};
                model.addRow(strArray);
            }
            progressBar.setValue(progress);
        }

        public void processComplete(List<BeanContact> contacts) {
            progressBar.setValue(progressBar.getMaximum());
        }

        /**
         * @param table the table to set
         */
        public void setTable(JTable table) {
            this.table = table;
        }

        /**
         * @param progressBar the progressBar to set
         */
        public void setProgressBar(JProgressBar progressBar) {
            this.progressBar = progressBar;
        }
    }


    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package swingworkertest;

    import java.util.List;

    /**
     *
     * @author Administrator
     */
    public interface IProgressHandle {
        public abstract void processInProgress(List<BeanContact> contacts,int progress);
        public abstract void processComplete(List<BeanContact> contacts);
    }


    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package swingworkertest;

    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.SwingWorker;

    /**
     *
     * @author Administrator
     */
    public class LoadContactsTask extends SwingWorker<List<BeanContact>, BeanContact> {

        private String fileName = null;
        private IProgressHandle progressHandle = null;
        private List<BeanContact> contacts = null;
        private int lineCnt = 0;

        public LoadContactsTask(String fileName) {
            this.fileName = fileName;
            contacts = new ArrayList<BeanContact>();
        }

        @Override
        protected List<BeanContact> doInBackground() throws Exception {
            BufferedReader reader = new BufferedReader(new FileReader("c:/contacts.cff"));
            String line = null;
            while ((line = reader.readLine()) != null) {
                String[] strContacts = line.split(",");
                BeanContact contact = new BeanContact();
                contact.setName(strContacts[0]);
                contact.setSex(strContacts[1]);
                contact.setPhone(strContacts[2]);
                contact.setEmail(strContacts[3]);

                lineCnt++;
                publish(contact);
                contacts.add(contact);
               
                Thread.sleep(100);
            }
            return contacts;
        }

        /**
         * @param progressHandle the progressHandle to set
         */
        public void setProgressHandle(IProgressHandle progressHandle) {
            this.progressHandle = progressHandle;
        }

        @Override
        protected void process(List<BeanContact> chunks) {
            if (progressHandle != null) {
                progressHandle.processInProgress(chunks, lineCnt * 100 / 10000);
            }
        }

        @Override
        protected void done() {
            if (progressHandle != null) {
                progressHandle.processComplete(contacts);
            }
        }
    }

    posted on 2011-06-26 11:10 Gavin Li 閱讀(3760) 評論(0)  編輯  收藏 所屬分類: Java

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


    網站導航:
     
    主站蜘蛛池模板: 日韩亚洲人成在线综合日本| 亚洲综合色视频在线观看| a毛片免费在线观看| 亚洲日韩人妻第一页| 亚洲首页在线观看| 免费国产黄网站在线观看| 亚洲国产精品lv| 国产产在线精品亚洲AAVV| 91精品免费观看| 亚洲区精品久久一区二区三区| 国产成人无码免费网站| 亚洲午夜久久久久妓女影院| 国产一级在线免费观看| 久久国产精品亚洲一区二区| 3d成人免费动漫在线观看| 亚洲日韩国产一区二区三区| 国产麻豆成人传媒免费观看| 亚洲激情电影在线| 浮力影院第一页小视频国产在线观看免费 | 91精品手机国产免费| 亚洲精品免费在线视频| 男女一边摸一边做爽的免费视频| 毛片在线看免费版| 亚洲自偷精品视频自拍| 二个人看的www免费视频| 亚洲AV无码专区国产乱码4SE| 免费的黄色的网站| 国产色爽女小说免费看| 久久嫩草影院免费看夜色| 亚洲高清不卡视频| 亚洲AV成人精品日韩一区18p| 亚洲自偷自偷在线成人网站传媒| 日本免费一区二区三区| 亚洲国产三级在线观看| 真人做A免费观看| 思思久久99热免费精品6| 亚洲v国产v天堂a无码久久| 国产精成人品日日拍夜夜免费| 国产亚洲精品美女久久久| www视频在线观看免费| 中文字幕在线观看亚洲|