仅执行SwingWorker的一个实例

时间:2014-07-16 12:56:52

标签: java swing concurrency swingworker

假设我有一个Java GUI,它在面板中显示40个来自所选区域的批处理对象,可以从A到Z.

从数据库中查询40个Batch对象,按区域缓存它们,以便每次对区域的每个请求都不涉及数据库。

public class BatchView
{

  private int drawIt(Graphics g, String zone)
  {
     for(int i = 0; i<40; i++)
       {
          Batch tmpBatch = BatchDAO.getBatch(zone, i);
          //draw the tmpBatch object
       }
  }
}

public class BatchDAO 
{
  public static MyCache cache = new MyCache(5000);

  public getAllBatches(String zone)
  {
    ArrayList<Batch> batchArrayList = cache.get("batch-" + zone);
    if(batchArrayList == null)
    {
        BuildBatchSwingWorker buildBatchSwingWorker = new BuildBatchSwingWorker(zone);
        buildBatchSwingWorker.execute();
    }
    return batchList;
  }

  public Batch getBatch(String zone, int id)
  {
     //here I don't query database but exploit the cache
     ArrayList<Batch> batchArrayList = getAllBatches(String zone);
     for(int i = 0; i< batchArrayList.size(); i++)
     {
       if(batchArrayList.get(i).getId() == i)
            return batchArrayList.get(i);
     }
     //if batch is not found it means it hasn't loaded yet so I return null
     return null;
  }
}

假设使用一系列通知正确更新缓存,并且每次drawIt()方法正确更新时,如何进行更新,以便不会同时为同一区域多次调用BuildBatchSwingWorker?

2 个答案:

答案 0 :(得分:1)

鉴于您的代码,我认为您真正关心的不是SwingWorker执行多少次,而是只执行一次数据库调用,然后使用BatchDAO缓存。

你需要正确地分离责任,缓存维护是BatchDAO类的工作,因此摇摆工作者与它无关:

public class BatchDAO {
    ...
    public getAllBatches(String zone) {
        ArrayList<Batch> batchArrayList = cache.get("batch-" + zone);
        if(batchArrayList == null) {
            // here goes database call not swing worker!
        }
        return batchList;
    }
    ...
}

然后在GUI类中执行swing worker(它所属的位置):

public class BatchView {

    private int drawIt(Graphics g, String zone) {
        SwingWorker<Void, Batch> worker = new SwingWorker<Void, Batch>() {
            @Override
            protected Void doInBackground() throws Exception {
                for(int i = 0; i<40; i++) {
                    Batch tmpBatch = BatchDAO.getBatch(zone, i);
                    publish(tmpBatch);
                 }
                 return null;
             }

             @Override
             protected void process(List<Batch> batches) {
                 for(Batch batch : batches) {
                     //draw the batch object
                 }
             }
         };

         worker.execute();
    }

}

注意如果cache.get("batch-" + zone) == null那么数据库调用只执行一次,但如果没有,那么你将使用你的chache并且doInBackground()方法将在眨眼间执行,我认为是你的目标。


题外话

由于我在BatchView课程中看到了Graphics个参数作为参数。构造函数,我建议你仔细阅读Performing Custom Painting教程,以避免自定义绘制不需要的问题(当然,如果你还没有读过它)。

答案 1 :(得分:0)

这是你可以调用的Swing实用程序的一个很好的例子:)

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

    package com.verve.swinguti;

    import javax.swing.SwingUtilities;

    /**
     *
     * @author kishan
     */
    public class Utilities extends javax.swing.JFrame {

        /**
         * Creates new form Utilities
         */
        public Utilities() {
            initComponents();
        }

        /**
         * 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() {

            jPanel1 = new javax.swing.JPanel();
            jButton2 = new javax.swing.JButton();
            jButton1 = new javax.swing.JButton();

            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

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

            javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
            jPanel1.setLayout(jPanel1Layout);
            jPanel1Layout.setHorizontalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addGap(71, 71, 71)
                    .addComponent(jButton2)
                    .addContainerGap(155, Short.MAX_VALUE))
            );
            jPanel1Layout.setVerticalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addGap(118, 118, 118)
                    .addComponent(jButton2)
                    .addContainerGap(128, Short.MAX_VALUE))
            );

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

            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(jButton1)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addContainerGap())
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jButton1)
                            .addGap(0, 0, Short.MAX_VALUE))
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addContainerGap())
            );

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

        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
            try {
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            for (int i = 0; i < 10; i++) {
                                System.out.println("This is Good Example**");
                                Thread.sleep(2000);
                            }

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });

            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
            try {
                System.out.println("This is Second Button");

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * @param args the command line arguments
         */
        public static void main(String args[]) {
            /*
             * Set the Nimbus look and feel
             */
            //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
            /*
             * If Nimbus (introduced in Java SE 6) is not available, stay with the
             * default look and feel. For details see
             * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
             */
            try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (ClassNotFoundException ex) {
                java.util.logging.Logger.getLogger(Utilities.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (InstantiationException ex) {
                java.util.logging.Logger.getLogger(Utilities.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                java.util.logging.Logger.getLogger(Utilities.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                java.util.logging.Logger.getLogger(Utilities.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }
            //</editor-fold>

            /*
             * Create and display the form
             */
            java.awt.EventQueue.invokeLater(new Runnable() {

                public void run() {
                    new Utilities().setVisible(true);
                }
            });
        }
        // Variables declaration - do not modify
        private javax.swing.JButton jButton1;
        private javax.swing.JButton jButton2;
        private javax.swing.JPanel jPanel1;
        // End of variables declaration
    }

See this click button1 and u wont be able to click other button till it completes process of button1