JAL-2587 Update overview progress bar while drawing rows too
[jalview.git] / src / jalview / renderer / OverviewRenderer.java
index 913c870..416defb 100644 (file)
@@ -22,6 +22,7 @@ package jalview.renderer;
 
 import jalview.api.AlignmentColsCollectionI;
 import jalview.api.AlignmentRowsCollectionI;
+import jalview.api.RendererListenerI;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.SequenceI;
@@ -32,9 +33,17 @@ import jalview.viewmodel.OverviewDimensions;
 import java.awt.Color;
 import java.awt.Graphics;
 import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeSupport;
 
 public class OverviewRenderer
 {
+  public static final String UPDATE = "OverviewUpdate";
+
+  private static final int MAX_PROGRESS = 100;
+
+  private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
+          this);
+
   private FeatureColourFinder finder;
 
   private jalview.api.SequenceRenderer sr;
@@ -48,8 +57,11 @@ public class OverviewRenderer
   // raw number of pixels to allocate to each row
   private float pixelsPerSeq;
 
+  // height in pixels of graph
+  private int graphHeight;
+
   // flag to indicate whether to halt drawing
-  private boolean redraw = false;
+  private volatile boolean redraw = false;
 
   public OverviewRenderer(jalview.api.SequenceRenderer seqRenderer,
           FeatureRenderer fr, OverviewDimensions od)
@@ -59,6 +71,7 @@ public class OverviewRenderer
 
     pixelsPerCol = od.getPixelsPerCol();
     pixelsPerSeq = od.getPixelsPerSeq();
+    graphHeight = od.getGraphHeight();
     miniMe = new BufferedImage(od.getWidth(), od.getHeight(),
             BufferedImage.TYPE_INT_RGB);
   }
@@ -78,6 +91,11 @@ public class OverviewRenderer
     int rgbcolor = Color.white.getRGB();
     int seqIndex = 0;
     int pixelRow = 0;
+    int alignmentHeight = miniMe.getHeight() - graphHeight;
+    int totalPixels = miniMe.getWidth() * alignmentHeight;
+
+    int lastRowUpdate = 0;
+    changeSupport.firePropertyChange(UPDATE, -1, 0);
 
     for (int alignmentRow : rows)
     {
@@ -127,17 +145,49 @@ public class OverviewRenderer
             }
           }
 
+          sendProgressUpdate((pixelCol + 1) * (endRow - pixelRow),
+                  totalPixels, lastRowUpdate);
           pixelCol = endCol + 1;
         }
         colIndex++;
       }
-      pixelRow = endRow + 1;
+
+      if (pixelRow != endRow + 1)
+      {
+        lastRowUpdate = sendProgressUpdate(endRow + 1, alignmentHeight, 0);
+        pixelRow = endRow + 1;
+      }
       seqIndex++;
     }
+
+    // final update to progress bar if present
+    if (redraw)
+    {
+      sendProgressUpdate(pixelRow - 1, alignmentHeight, 0);
+    }
+    else
+    {
+      sendProgressUpdate(alignmentHeight, miniMe.getHeight(), 0);
+    }
     return miniMe;
   }
 
   /*
+   * Calculate progress update value and fire event
+   */
+  private int sendProgressUpdate(int position, int maximum, int offset)
+  {
+    int newUpdate = offset
+            + Math.round(MAX_PROGRESS * ((float) position / maximum));
+    if (newUpdate > offset)
+    {
+      changeSupport.firePropertyChange(UPDATE, offset, newUpdate);
+      return newUpdate;
+    }
+    return offset;
+  }
+
+  /*
    * Find the colour of a sequence at a specified column position
    */
   private int getColumnColourFromSequence(jalview.datamodel.SequenceI seq,
@@ -186,8 +236,10 @@ public class OverviewRenderer
     {
       if (redraw)
       {
+        changeSupport.firePropertyChange(UPDATE, MAX_PROGRESS - 1, 0);
         break;
       }
+
       if (alignmentCol >= annotations.length)
       {
         break; // no more annotations to draw here
@@ -217,10 +269,13 @@ public class OverviewRenderer
 
           g.fillRect(pixelCol, y - height, endCol - pixelCol + 1, height);
         }
+
         pixelCol = endCol + 1;
         colIndex++;
       }
     }
+    changeSupport.firePropertyChange(UPDATE, MAX_PROGRESS - 1,
+            MAX_PROGRESS);
   }
 
   public void setRedraw(boolean b)
@@ -230,4 +285,14 @@ public class OverviewRenderer
       redraw = b;
     }
   }
+
+  public void addPropertyChangeListener(RendererListenerI listener)
+  {
+    changeSupport.addPropertyChangeListener(listener);
+  }
+
+  public void removePropertyChangeListener(RendererListenerI listener)
+  {
+    changeSupport.removePropertyChangeListener(listener);
+  }
 }