diff --git a/uk/ac/sanger/artemis/components/alignment/BamUtils.java b/uk/ac/sanger/artemis/components/alignment/BamUtils.java
index a870c46e29a0a57e48fedecf04e23e0f56fe66cb..ee271b58f4444c5e16def47dbb5011a0d659bdbb 100644
--- a/uk/ac/sanger/artemis/components/alignment/BamUtils.java
+++ b/uk/ac/sanger/artemis/components/alignment/BamUtils.java
@@ -23,130 +23,20 @@
  */
 package uk.ac.sanger.artemis.components.alignment;
 
-import java.awt.Container;
-import java.awt.Frame;
-import java.text.DecimalFormat;
-import java.util.Arrays;
 import java.util.Hashtable;
-import java.util.List;
 import java.util.Vector;
 
-import javax.swing.JFrame;
-
 import net.sf.samtools.SAMFileReader;
 import net.sf.samtools.SAMRecord;
 import net.sf.samtools.util.CloseableIterator;
 import uk.ac.sanger.artemis.Feature;
 import uk.ac.sanger.artemis.FeatureSegmentVector;
-import uk.ac.sanger.artemis.FeatureVector;
-import uk.ac.sanger.artemis.components.EntryEdit;
-import uk.ac.sanger.artemis.components.FileViewer;
-import uk.ac.sanger.artemis.components.MultiComparator;
 import uk.ac.sanger.artemis.io.Range;
 
 class BamUtils
 {
-  /**
-   * Read count for selected reads.
-   * @param features
-   * @param refName
-   * @param samFileReaderHash
-   * @param bamList
-   * @param seqNames
-   * @param offsetLengths
-   * @param concatSequences
-   * @param seqLengths
-   * @param samRecordFlagPredicate
-   * @param samRecordMapQPredicate
-   * @param contained
-   * @param useIntrons
-   * @param mappedReads
-   */
-  protected static void countReads(final FeatureVector features,
-                                   final String refName,
-                                   final Hashtable<String, SAMFileReader> samFileReaderHash,
-                                   final List<String> bamList, 
-                                   final Vector<String> seqNames,
-                                   final Hashtable<String, Integer> offsetLengths,
-                                   final boolean concatSequences, 
-                                   final Hashtable<String, Integer> seqLengths,
-                                   final SAMRecordPredicate samRecordFlagPredicate,
-                                   final SAMRecordMapQPredicate samRecordMapQPredicate,
-                                   final boolean contained,
-                                   final boolean useIntrons,
-                                   final int mappedReads[])
-  {
-    Hashtable<String, List<Float>> featureReadCount = new Hashtable<String, List<Float>>();
-
-    for(int i=0; i<features.size(); i++)
-    {     
-      Feature f = features.elementAt(i);
-      
-      int start  = f.getRawFirstBase();
-      int end    = f.getRawLastBase();
-      float fLen = getFeatureLength(f);
-      List<Float> sampleCounts = new Vector<Float>();
-        
-      for(int j=0; j<bamList.size(); j++)
-      {
-        String bam = bamList.get(j);
-        float cnt = 0;
-        if(!useIntrons && f.getSegments().size() > 1)
-        {
-          for(int k=0; k<f.getSegments().size(); k++)
-          {
-            start = f.getSegments().elementAt(k).getRawRange().getStart();
-            end   = f.getSegments().elementAt(k).getRawRange().getEnd();
-            cnt += getCount(start, end, bam, refName, samFileReaderHash, 
-              seqNames, offsetLengths, concatSequences, seqLengths, 
-              samRecordFlagPredicate, samRecordMapQPredicate, contained); 
-          }
-        }
-        else
-          cnt = getCount(start, end, bam, refName, samFileReaderHash, 
-              seqNames, offsetLengths, concatSequences, seqLengths, 
-              samRecordFlagPredicate, samRecordMapQPredicate, contained); 
 
-        if(mappedReads != null)
-          cnt = (cnt / ( ((float)mappedReads[j]/1000000.f) * (fLen/1000.f) )) ;
-        
-        sampleCounts.add(cnt);
-      }
-      featureReadCount.put(f.getSystematicName(), sampleCounts);
-    }
-
-    DecimalFormat df = new DecimalFormat("0.00##");
-    StringBuffer buff = new StringBuffer();
-    for(int j=0; j<bamList.size(); j++)
-    {
-      String bam = bamList.get(j);
-      buff.append("#BAM: "+bam);
-      if(mappedReads != null)
-        buff.append(" Mapped Reads/million: "+ df.format( ((float)mappedReads[j]) / 1000000.f) );
-      buff.append("\n");
-    }
-    buff.append("\n");
-    
-    Object[] readKey = featureReadCount.keySet().toArray();
-    Arrays.sort(readKey);
-    
-    for (Object fId : readKey ) {
-      buff.append(fId+"\t");
-      List<Float> cnts = featureReadCount.get(fId);
-      for(int i=0; i<cnts.size(); i++)
-        buff.append(df.format(cnts.get(i)) + (i<cnts.size()-1 ? "\t" : ""));
-      buff.append("\n");
-    }
-
-    FileViewer viewer;
-    if(mappedReads != null)
-      viewer = new FileViewer ("RPKM", true, false, true);
-    else
-      viewer = new FileViewer ("Read Count", true, false, true);
-    viewer.getTextPane().setText(buff.toString());
-  }
-
-  private static float getFeatureLength(Feature f)
+  protected static float getFeatureLength(Feature f)
   {
     FeatureSegmentVector segs = f.getSegments();
     int len = 0;
@@ -174,7 +64,7 @@ class BamUtils
    * @param contained
    * @return
    */
-  private static int getCount(
+  protected static int getCount(
       final int start,
       final int end,
       final String bam,
@@ -226,82 +116,7 @@ class BamUtils
     return cnt;
   }
 
-  /**
-   * Calculate the total number of mapped reads.
-   * @param refName
-   * @param samFileReaderHash
-   * @param bamList
-   * @param seqNames
-   * @param offsetLengths
-   * @param concatSequences
-   * @param seqLengths
-   * @param sequenceLength
-   * @return
-   */
-  protected static int[] getTotalMappedReads(
-      final String refName,
-      final Hashtable<String, SAMFileReader> samFileReaderHash,
-      final List<String> bamList, 
-      final Vector<String> seqNames,
-      final Hashtable<String, Integer> offsetLengths,
-      final boolean concatSequences, 
-      final Hashtable<String, Integer> seqLengths,
-      final int sequenceLength,
-      final SAMRecordPredicate samRecordFlagPredicate, 
-      SAMRecordMapQPredicate samRecordMapQPredicate)
-  {
-    int MAX_BASE_CHUNK = 2000*60;
-    int mapped[] = new int[bamList.size()];
-    boolean contained = false;
-
-    for (int i = 0; i < sequenceLength; i += MAX_BASE_CHUNK)
-    {
-      int sbegc = i;
-      int sendc = i + MAX_BASE_CHUNK - 1;
-
-      for (int j=0; j<bamList.size(); j++)
-      {
-        String bam = bamList.get(j);
-        if (concatSequences)
-        {
-          int len = 0;
-          int lastLen = 1;
-          for (String name : seqNames)
-          {
-            int thisLength = seqLengths.get(name);
-            len += thisLength;
-
-            if ((lastLen >= sbegc && lastLen < sendc)
-                || (len >= sbegc && len < sendc)
-                || (sbegc >= lastLen && sbegc < len)
-                || (sendc >= lastLen && sendc < len))
-            {
-              int offset = offsetLengths.get(name);
-              int thisStart = sbegc - offset;
-              if (thisStart < 1)
-                thisStart = 1;
-              int thisEnd = sendc - offset;
-              if (thisEnd > thisLength)
-                thisEnd = thisLength;
-
-              mapped[j] += count(bam, samFileReaderHash, name, thisStart, thisEnd,
-                  samRecordFlagPredicate, samRecordMapQPredicate, contained);
-
-            }
-            lastLen = len;
-          }
-        }
-        else
-        {
-          mapped[j] += count(bam, samFileReaderHash, refName, sbegc, sendc,
-              samRecordFlagPredicate, samRecordMapQPredicate, contained);
-        }
-      }
-    }
-    return mapped;
-  }
-  
-  private static int count(String bam, 
+  protected static int count(String bam, 
                     Hashtable<String, SAMFileReader> samFileReaderHash, 
                     String refName, 
                     int start, 
@@ -330,18 +145,6 @@ class BamUtils
     it.close();
     return cnt;
   }
-  
-  protected static Container getBamContainer(BamView bamView)
-  {
-    Frame fs[] = JFrame.getFrames();
-    for(Frame f: fs)
-    {
-      if( f instanceof JFrame && 
-         ((JFrame)f) instanceof EntryEdit ||
-         ((JFrame)f) instanceof MultiComparator)
-        return ((JFrame)f).getContentPane();
-    }
-    return bamView;
-  }
+
 }
 
diff --git a/uk/ac/sanger/artemis/components/alignment/BamView.java b/uk/ac/sanger/artemis/components/alignment/BamView.java
index 608c75128fba7d8d6f25e3f0ccb707037d735eb7..ace4e38e56d0098403eb1a76f20ef330186ddf14 100644
--- a/uk/ac/sanger/artemis/components/alignment/BamView.java
+++ b/uk/ac/sanger/artemis/components/alignment/BamView.java
@@ -29,8 +29,6 @@ import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Component;
 import java.awt.Composite;
-import java.awt.Container;
-import java.awt.Cursor;
 import java.awt.Dimension;
 import java.awt.FlowLayout;
 import java.awt.FontMetrics;
@@ -2016,10 +2014,8 @@ public class BamView extends JPanel
     {
       public void actionPerformed(ActionEvent e)
       {
-        Container c = BamUtils.getBamContainer(BamView.this);
-        c.setCursor(new Cursor(Cursor.WAIT_CURSOR));
         FeatureVector features = feature_display.getSelection().getAllFeatures();
-        
+
         JCheckBox overlap = new JCheckBox("Include all overlapping reads", true);
         overlap.setToolTipText("Include reads that partially overlap the feature");
         JCheckBox spliced = new JCheckBox("Introns included", true);
@@ -2028,11 +2024,10 @@ public class BamView extends JPanel
         yBox.add(spliced);
         JOptionPane.showMessageDialog(null, yBox, "Read Count Option", JOptionPane.INFORMATION_MESSAGE);
         
-        BamUtils.countReads(features, (String)combo.getSelectedItem(), samFileReaderHash, bamList,
+        new MappedReads(features, (String)combo.getSelectedItem(), samFileReaderHash, bamList,
             seqNames, offsetLengths, concatSequences, seqLengths, 
             samRecordFlagPredicate, samRecordMapQPredicate,
-            !overlap.isSelected(), spliced.isSelected(), null);
-        c.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+            !overlap.isSelected(), spliced.isSelected());
       } 
     });
     
@@ -2044,10 +2039,8 @@ public class BamView extends JPanel
     {
       public void actionPerformed(ActionEvent e)
       {
-        Container c = BamUtils.getBamContainer(BamView.this);
-        c.setCursor(new Cursor(Cursor.WAIT_CURSOR));
         FeatureVector features = feature_display.getSelection().getAllFeatures();
-        
+
         JCheckBox overlap = new JCheckBox("Include all overlapping reads", true);
         overlap.setToolTipText("Include reads that partially overlap the feature");
         JCheckBox spliced = new JCheckBox("Introns included", true);
@@ -2061,18 +2054,11 @@ public class BamView extends JPanel
           seqlen = feature_display.getSequenceLength();
         else if(bases != null)
           seqlen = bases.getLength();
-
-        int mappedReads[] =
-          BamUtils.getTotalMappedReads((String)combo.getSelectedItem(),
-              samFileReaderHash, bamList, seqNames, offsetLengths, concatSequences, 
-              offsetLengths, seqlen, samRecordFlagPredicate, samRecordMapQPredicate);
-
-        logger4j.debug("TOTAL MAPPED READS "+mappedReads);
-        BamUtils.countReads(features, (String)combo.getSelectedItem(), samFileReaderHash, bamList,
-            seqNames, offsetLengths, concatSequences, seqLengths, 
-            samRecordFlagPredicate, samRecordMapQPredicate,
-            !overlap.isSelected(), spliced.isSelected(), mappedReads);
-        c.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+        
+        new MappedReads(features, (String)combo.getSelectedItem(),
+            samFileReaderHash, bamList, seqNames, offsetLengths, concatSequences, 
+            offsetLengths, seqlen, samRecordFlagPredicate, samRecordMapQPredicate,
+            !overlap.isSelected(), spliced.isSelected());
       } 
     });
 
diff --git a/uk/ac/sanger/artemis/components/alignment/MappedReads.java b/uk/ac/sanger/artemis/components/alignment/MappedReads.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca71b7e99a375667375f9ebfb4951cef8f00231e
--- /dev/null
+++ b/uk/ac/sanger/artemis/components/alignment/MappedReads.java
@@ -0,0 +1,327 @@
+package uk.ac.sanger.artemis.components.alignment;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.text.DecimalFormat;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+
+import uk.ac.sanger.artemis.Feature;
+import uk.ac.sanger.artemis.FeatureVector;
+import uk.ac.sanger.artemis.components.FileViewer;
+import uk.ac.sanger.artemis.components.SwingWorker;
+
+import net.sf.samtools.SAMFileReader;
+
+public class MappedReads
+{
+  private JProgressBar progressBar;
+  private JLabel progressTxt = new JLabel();
+
+  private FeatureVector features;
+  private String refName;
+  private Hashtable<String, SAMFileReader> samFileReaderHash;
+  private List<String> bamList;
+  private Vector<String> seqNames;
+  private Hashtable<String, Integer> offsetLengths;
+  private boolean concatSequences;
+  private Hashtable<String, Integer> seqLengths;
+  private int sequenceLength;
+  private SAMRecordPredicate samRecordFlagPredicate;
+  private SAMRecordMapQPredicate samRecordMapQPredicate;
+  private boolean contained;
+  private boolean useIntrons;
+  private JDialog dialog = new JDialog((JFrame)null, "Calculating", true);;
+    
+  private int mappedReads[];
+    
+  /**
+   * Calculate the total number of mapped reads.
+   * @param refName
+   * @param samFileReaderHash
+   * @param bamList
+   * @param seqNames
+   * @param offsetLengths
+   * @param concatSequences
+   * @param seqLengths
+   * @param sequenceLength
+   */
+  public MappedReads(
+      final FeatureVector features,
+      final String refName,
+      final Hashtable<String, SAMFileReader> samFileReaderHash,
+      final List<String> bamList, 
+      final Vector<String> seqNames,
+      final Hashtable<String, Integer> offsetLengths,
+      final boolean concatSequences,
+      final Hashtable<String, Integer> seqLengths, 
+      final int sequenceLength,
+      final SAMRecordPredicate samRecordFlagPredicate,
+      SAMRecordMapQPredicate samRecordMapQPredicate,
+      final boolean contained, 
+      final boolean useIntrons)
+  {
+    this.features = features;
+    this.refName = refName;
+    this.samFileReaderHash = samFileReaderHash;
+    this.bamList = bamList;
+    this.seqNames = seqNames;
+    this.offsetLengths = offsetLengths;
+    this.concatSequences = concatSequences;
+    this.seqLengths = seqLengths;
+    this.sequenceLength = sequenceLength;
+    this.samRecordFlagPredicate = samRecordFlagPredicate;
+    this.samRecordMapQPredicate = samRecordMapQPredicate;
+    this.contained = contained;
+    this.useIntrons = useIntrons;
+    
+    progressBar = new JProgressBar(0, sequenceLength);
+    progressBar.setValue(0);
+    progressBar.setStringPainted(true);
+
+    JPanel panel = new JPanel(new BorderLayout());
+    progressTxt.setText("Total number of mapped reads");
+    panel.add(progressTxt, BorderLayout.NORTH);
+    panel.add(progressBar, BorderLayout.CENTER);
+
+    dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+    panel.setOpaque(true);
+    dialog.setContentPane(panel);
+    dialog.pack();
+    centerDialog();
+
+    CalculateTotalMappedReads cmr = new CalculateTotalMappedReads();
+    cmr.start();
+    dialog.setVisible(true);
+  }
+
+  /**
+   * Read count for selected features.
+   * @param features
+   * @param refName
+   * @param samFileReaderHash
+   * @param bamList
+   * @param seqNames
+   * @param offsetLengths
+   * @param concatSequences
+   * @param seqLengths
+   * @param samRecordFlagPredicate
+   * @param samRecordMapQPredicate
+   * @param contained
+   * @param useIntrons
+   */
+  public MappedReads(
+      final FeatureVector features, 
+      final String refName,
+      final Hashtable<String, SAMFileReader> samFileReaderHash,
+      final List<String> bamList, 
+      final Vector<String> seqNames,
+      final Hashtable<String, Integer> offsetLengths,
+      final boolean concatSequences,
+      final Hashtable<String, Integer> seqLengths,
+      final SAMRecordPredicate samRecordFlagPredicate,
+      final SAMRecordMapQPredicate samRecordMapQPredicate,
+      final boolean contained, 
+      final boolean useIntrons)
+  {
+    this.features = features;
+    this.refName = refName;
+    this.samFileReaderHash = samFileReaderHash;
+    this.bamList = bamList;
+    this.seqNames = seqNames;
+    this.offsetLengths = offsetLengths;
+    this.concatSequences = concatSequences;
+    this.seqLengths = seqLengths;
+    this.samRecordFlagPredicate = samRecordFlagPredicate;
+    this.samRecordMapQPredicate = samRecordMapQPredicate;
+    this.contained = contained;
+    this.useIntrons = useIntrons;
+    
+    progressBar = new JProgressBar(0, features.size());
+    progressBar.setValue(0);
+    progressBar.setStringPainted(true);
+
+    JPanel panel = new JPanel(new BorderLayout());
+    progressTxt.setText("Number of mapped reads for "+features.size()+" features");
+    panel.add(progressTxt, BorderLayout.NORTH);
+    panel.add(progressBar, BorderLayout.CENTER);
+
+    panel.setOpaque(true);
+    dialog.setContentPane(panel);
+    dialog.pack();
+    centerDialog();
+    
+    CalculateMappedReads cmr = new CalculateMappedReads();
+    cmr.start();
+    dialog.setVisible(true);
+  }
+
+  private void centerDialog()
+  {
+    final Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+    final int x_position =(screen.width - dialog.getSize().width) / 2;
+    int y_position =(screen.height - dialog.getSize().height) / 2;
+
+    if(y_position < 10) 
+      y_position = 10;
+    dialog.setLocation(new Point(x_position, y_position));  
+  }
+  
+  class CalculateMappedReads extends SwingWorker
+  {
+    Hashtable<String, List<Float>> featureReadCount;
+    public Object construct()
+    {
+      featureReadCount = new Hashtable<String, List<Float>>();
+      for (int i = 0; i < features.size(); i++)
+      {
+        Feature f = features.elementAt(i);
+        progressBar.setValue(i);
+
+        int start = f.getRawFirstBase();
+        int end = f.getRawLastBase();
+        float fLen = BamUtils.getFeatureLength(f);
+        List<Float> sampleCounts = new Vector<Float>();
+
+        for (int j = 0; j < bamList.size(); j++)
+        {
+          String bam = bamList.get(j);
+          float cnt = 0;
+          if (!useIntrons && f.getSegments().size() > 1)
+          {
+            for (int k = 0; k < f.getSegments().size(); k++)
+            {
+              start = f.getSegments().elementAt(k).getRawRange().getStart();
+              end = f.getSegments().elementAt(k).getRawRange().getEnd();
+              cnt += BamUtils.getCount(start, end, bam, refName, samFileReaderHash,
+                  seqNames, offsetLengths, concatSequences, seqLengths,
+                  samRecordFlagPredicate, samRecordMapQPredicate, contained);
+            }
+          }
+          else
+            cnt = BamUtils.getCount(start, end, bam, refName, samFileReaderHash, seqNames,
+                offsetLengths, concatSequences, seqLengths,
+                samRecordFlagPredicate, samRecordMapQPredicate, contained);
+
+          if (mappedReads != null)
+            cnt = (cnt / (((float) mappedReads[j] / 1000000.f) * (fLen / 1000.f)));
+
+          sampleCounts.add(cnt);
+        }
+        featureReadCount.put(f.getSystematicName(), sampleCounts);
+      }
+      return null;
+    }
+    
+    public void finished() 
+    {
+      DecimalFormat df = new DecimalFormat("0.00##");
+      StringBuffer buff = new StringBuffer();
+      for (int j = 0; j < bamList.size(); j++)
+      {
+        String bam = bamList.get(j);
+        buff.append("#BAM: " + bam);
+        if (mappedReads != null)
+          buff.append(" Mapped Reads/million: "
+              + df.format(((float) mappedReads[j]) / 1000000.f));
+        buff.append("\n");
+      }
+      buff.append("\n");
+
+      Object[] readKey = featureReadCount.keySet().toArray();
+      Arrays.sort(readKey);
+
+      for (Object fId : readKey)
+      {
+        buff.append(fId + "\t");
+        List<Float> cnts = featureReadCount.get(fId);
+        for (int i = 0; i < cnts.size(); i++)
+          buff.append(df.format(cnts.get(i)) + (i < cnts.size() - 1 ? "\t" : ""));
+        buff.append("\n");
+      }
+
+      FileViewer viewer;
+      if (mappedReads != null)
+        viewer = new FileViewer("RPKM", true, false, true);
+      else
+        viewer = new FileViewer("Read Count", true, false, true);
+      viewer.getTextPane().setText(buff.toString());
+      
+      dialog.dispose();
+    }
+  }
+  
+  class CalculateTotalMappedReads extends SwingWorker
+  {
+    public Object construct()
+    {
+      int MAX_BASE_CHUNK = 2000 * 60;
+      mappedReads = new int[bamList.size()];
+      boolean contained = false;
+      for (int i = 0; i < sequenceLength; i += MAX_BASE_CHUNK)
+      {
+        progressBar.setValue(i);
+        int sbegc = i;
+        int sendc = i + MAX_BASE_CHUNK - 1;
+
+        for (int j = 0; j < bamList.size(); j++)
+        {
+          String bam = bamList.get(j);
+          if (concatSequences)
+          {
+            int len = 0;
+            int lastLen = 1;
+            for (String name : seqNames)
+            {
+              int thisLength = seqLengths.get(name);
+              len += thisLength;
+
+              if ((lastLen >= sbegc && lastLen < sendc)
+                  || (len >= sbegc && len < sendc)
+                  || (sbegc >= lastLen && sbegc < len)
+                  || (sendc >= lastLen && sendc < len))
+              {
+                int offset = offsetLengths.get(name);
+                int thisStart = sbegc - offset;
+                if (thisStart < 1)
+                  thisStart = 1;
+                int thisEnd = sendc - offset;
+                if (thisEnd > thisLength)
+                  thisEnd = thisLength;
+
+                mappedReads[j] += BamUtils.count(bam, samFileReaderHash, name,
+                    thisStart, thisEnd, samRecordFlagPredicate,
+                    samRecordMapQPredicate, contained);
+
+              }
+              lastLen = len;
+            }
+          }
+          else
+          {
+            mappedReads[j] += BamUtils.count(bam, samFileReaderHash, refName, sbegc,
+                sendc, samRecordFlagPredicate, samRecordMapQPredicate,
+                contained);
+          }
+        }
+      }
+      
+      progressBar.setValue(0);
+      progressBar.setMaximum(features.size());
+      progressTxt.setText("RPKM values for "+features.size()+" features");
+      CalculateMappedReads cmr = new CalculateMappedReads();
+      cmr.start();
+      return null;
+    } 
+  }
+}