X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FSeqCanvas.java;h=123e649838d401e19ed9d4667303e7fa44712f79;hb=da8e34c5aeee5e83aa844d374eb21e4c2e3cebef;hp=53c9bb402f80500edeeb8b9051f143a014a69e42;hpb=3ba95e6f2fa88014ba97c3f23a195ffeeba52a6a;p=jalview.git
diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java
index 53c9bb4..123e649 100755
--- a/src/jalview/gui/SeqCanvas.java
+++ b/src/jalview/gui/SeqCanvas.java
@@ -38,14 +38,14 @@ import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
+import java.awt.Rectangle;
import java.awt.RenderingHints;
-import java.awt.Shape;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.util.Iterator;
import java.util.List;
-import javax.swing.JComponent;
+import javax.swing.JPanel;
/**
* The Swing component on which the alignment sequences, and annotations (if
@@ -53,8 +53,14 @@ import javax.swing.JComponent;
* Wrapped mode, but not the scale above in Unwrapped mode.
*
*/
-public class SeqCanvas extends JComponent implements ViewportListenerI
+@SuppressWarnings("serial")
+public class SeqCanvas extends JPanel implements ViewportListenerI
{
+ /*
+ * pixels gap between sequences and annotations when in wrapped mode
+ */
+ static final int SEQS_ANNOTATION_GAP = 3;
+
private static final String ZEROS = "0000000000";
final FeatureRenderer fr;
@@ -69,7 +75,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
private final SequenceRenderer seqRdr;
- private boolean fastPaint = false;
+ boolean fastPaint = false;
private boolean fastpainting = false;
@@ -82,13 +88,14 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
private int labelWidthWest; // label left width in pixels if shown
- private int wrappedSpaceAboveAlignment; // gap between widths
+ int wrappedSpaceAboveAlignment; // gap between widths
- private int wrappedRepeatHeightPx; // height in pixels of wrapped width
+ int wrappedRepeatHeightPx; // height in pixels of wrapped width
private int wrappedVisibleWidths; // number of wrapped widths displayed
- private Graphics2D gg;
+ // Don't do this! Graphics handles are supposed to be transient
+ //private Graphics2D gg;
/**
* Creates a new SeqCanvas object.
@@ -109,7 +116,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
public SequenceRenderer getSequenceRenderer()
{
- return seqRdr;
+ return seqRdr;
}
public FeatureRenderer getFeatureRenderer()
@@ -195,7 +202,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
int yPos = ypos + charHeight;
int startX = startx;
int endX = endx;
-
+
if (av.hasHiddenColumns())
{
HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
@@ -231,6 +238,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
}
}
+
/*
* white fill the space for the scale
*/
@@ -255,6 +263,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
g.drawString(valueAsString, xOffset, y);
}
}
+
}
/**
@@ -268,6 +277,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
*
scrolling by trackpad, middle mouse button, or other device
* by moving the box in the Overview window
* programmatically to make a highlighted position visible
+ * pasting a block of sequences
*
*
* @param horizontal
@@ -277,18 +287,21 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
*/
public void fastPaint(int horizontal, int vertical)
{
- if (fastpainting || gg == null || img == null)
+
+ // effectively:
+ // if (horizontal != 0 && vertical != 0)
+ // throw new InvalidArgumentException();
+ if (fastpainting || img == null)
{
return;
}
fastpainting = true;
fastPaint = true;
-
try
{
int charHeight = av.getCharHeight();
int charWidth = av.getCharWidth();
-
+
ViewportRanges ranges = av.getRanges();
int startRes = ranges.getStartRes();
int endRes = ranges.getEndRes();
@@ -296,10 +309,6 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
int endSeq = ranges.getEndSeq();
int transX = 0;
int transY = 0;
-
- gg.copyArea(horizontal * charWidth, vertical * charHeight,
- img.getWidth(), img.getHeight(), -horizontal * charWidth,
- -vertical * charHeight);
if (horizontal > 0) // scrollbar pulled right, image to the left
{
@@ -334,13 +343,24 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
}
}
+
+ // System.err.println(">>> FastPaint to " + transX + " " + transY + " "
+ // + horizontal + " " + vertical + " " + startRes + " " + endRes
+ // + " " + startSeq + " " + endSeq);
+
+ Graphics gg = img.getGraphics();
+ gg.copyArea(horizontal * charWidth, vertical * charHeight,
+ img.getWidth(), img.getHeight(), -horizontal * charWidth,
+ -vertical * charHeight);
gg.translate(transX, transY);
drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
gg.translate(-transX, -transY);
+ gg.dispose();
// Call repaint on alignment panel so that repaints from other alignment
// panel components can be aggregated. Otherwise performance of the
// overview window and others may be adversely affected.
+ // System.out.println("SeqCanvas fastPaint() repaint() request...");
av.getAlignPanel().repaint();
} finally
{
@@ -351,77 +371,109 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
@Override
public void paintComponent(Graphics g)
{
- super.paintComponent(g);
-
+
+ if (av.getAlignPanel().getHoldRepaint())
+ {
+ return;
+ }
int charHeight = av.getCharHeight();
int charWidth = av.getCharWidth();
-
+
+ int availWidth = getWidth();
+ int availHeight = getHeight();
+
+ availWidth -= (availWidth % charWidth);
+ availHeight -= (availHeight % charHeight);
+
+ // BH 2019 can't possibly fastPaint if either width or height is 0
+
+ if (availWidth == 0 || availHeight == 0)
+ {
+ return;
+ }
+
ViewportRanges ranges = av.getRanges();
-
- int width = getWidth();
- int height = getHeight();
-
- width -= (width % charWidth);
- height -= (height % charHeight);
-
- drawSelectionGroup((Graphics2D) g,
- ranges.getStartRes(), ranges.getEndRes(),
- ranges.getStartSeq(), ranges.getEndSeq());
-
- if ((img != null) && (fastPaint
- || (getVisibleRect().width != g.getClipBounds().width)
- || (getVisibleRect().height != g.getClipBounds().height)))
+ int startRes = ranges.getStartRes();
+ int startSeq = ranges.getStartSeq();
+ int endRes = ranges.getEndRes();
+ int endSeq = ranges.getEndSeq();
+
+ // [JAL-3226] problem that JavaScript (or Java) may consolidate multiple
+ // repaint() requests in unpredictable ways. In this case, the issue was
+ // that in response to a CTRL-C/CTRL-V paste request, in Java a fast
+ // repaint request preceded two full requests, thus resulting
+ // in a full request for paint. In constrast, in JavaScript, the three
+ // requests were bundled together into one, so the fastPaint flag was
+ // still present for the second and third request.
+ //
+ // This resulted in incomplete painting.
+ //
+ // The solution was to set seqCanvas.fastPaint and idCanvas.fastPaint false
+ // in PaintRefresher when the target to be painted is one of those two
+ // components.
+ //
+ // BH 2019.04.22
+ //
+ // An initial idea; can be removed once we determine this issue is closed:
+ // if (av.isFastPaintDisabled())
+ // {
+ // fastPaint = false;
+ // }
+
+ Rectangle vis, clip;
+ if (img != null
+ && (fastPaint
+ || (vis = getVisibleRect()).width != (clip = g
+ .getClipBounds()).width
+ || vis.height != clip.height))
{
g.drawImage(img, 0, 0, this);
-
- drawSelectionGroup((Graphics2D) g, ranges.getStartRes(),
- ranges.getEndRes(), ranges.getStartSeq(), ranges.getEndSeq());
-
+ drawSelectionGroup((Graphics2D) g, startRes, endRes, startSeq,
+ endSeq);
fastPaint = false;
}
- else if (width > 0 && height > 0)
+ else
{
- /*
- * img is a cached version of the last view we drew, if any
- * if we have no img or the size has changed, make a new one
- */
- if (img == null || width != img.getWidth()
- || height != img.getHeight())
+ // img is a cached version of the last view we drew.
+ // If we have no img or the size has changed, make a new one.
+ //
+ if (img == null || availWidth != img.getWidth()
+ || availHeight != img.getHeight())
{
- img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- gg = (Graphics2D) img.getGraphics();
- gg.setFont(av.getFont());
+ img = new BufferedImage(availWidth, availHeight,
+ BufferedImage.TYPE_INT_RGB);
}
-
+
+ Graphics2D gg = (Graphics2D) img.getGraphics();
+ gg.setFont(av.getFont());
+
if (av.antiAlias)
{
gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
-
+
gg.setColor(Color.white);
- gg.fillRect(0, 0, img.getWidth(), img.getHeight());
-
+ gg.fillRect(0, 0, availWidth, availHeight);
+
if (av.getWrapAlignment())
{
- drawWrappedPanel(gg, getWidth(), getHeight(), ranges.getStartRes());
+ drawWrappedPanel(gg, availWidth, availHeight, ranges.getStartRes());
}
else
{
- drawPanel(gg, ranges.getStartRes(), ranges.getEndRes(),
- ranges.getStartSeq(), ranges.getEndSeq(), 0);
+ drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
}
- drawSelectionGroup(gg, ranges.getStartRes(),
- ranges.getEndRes(), ranges.getStartSeq(), ranges.getEndSeq());
+ drawSelectionGroup(gg, startRes, endRes, startSeq, endSeq);
g.drawImage(img, 0, 0, this);
+ gg.dispose();
}
if (av.cursorMode)
{
- drawCursor(g, ranges.getStartRes(), ranges.getEndRes(),
- ranges.getStartSeq(), ranges.getEndSeq());
+ drawCursor(g, startRes, endRes, startSeq, endSeq);
}
}
@@ -474,32 +526,31 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
}
/**
- * Returns the visible width of the canvas in residues, after allowing for
- * East or West scales (if shown)
+ * Using the current font, determine fields labelWidthEast and labelWidthWest,
+ * and return the number of residues that can fill the remaining width.
*
- * @param canvasWidth
+ * @param width
* the width in pixels (possibly including scales)
*
- * @return
+ * @return the visible width in residues, after allowing for East or West
+ * scales (if shown)
+ *
*/
- public int getWrappedCanvasWidth(int canvasWidth)
+ public int getWrappedCanvasWidth(int width)
{
int charWidth = av.getCharWidth();
FontMetrics fm = getFontMetrics(av.getFont());
- int labelWidth = 0;
-
- if (av.getScaleRightWrapped() || av.getScaleLeftWrapped())
- {
- labelWidth = getLabelWidth(fm);
- }
+ int labelWidth = (av.getScaleRightWrapped() || av.getScaleLeftWrapped()
+ ? getLabelWidth(fm)
+ : 0);
labelWidthEast = av.getScaleRightWrapped() ? labelWidth : 0;
labelWidthWest = av.getScaleLeftWrapped() ? labelWidth : 0;
- return (canvasWidth - labelWidthEast - labelWidthWest) / charWidth;
+ return (width - labelWidthEast - labelWidthWest) / charWidth;
}
/**
@@ -525,6 +576,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
maxWidth = Math.max(maxWidth, alignment.getSequenceAt(i).getEnd());
}
+ // quick int log10
int length = 0;
for (int i = maxWidth; i > 0; i /= 10)
{
@@ -539,18 +591,18 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
* window
*
* @param g
- * @param canvasWidth
+ * @param availWidth
* available width in pixels
- * @param canvasHeight
+ * @param availHeight
* available height in pixels
* @param startColumn
* the first column (0...) of the alignment to draw
*/
- public void drawWrappedPanel(Graphics g, int canvasWidth,
- int canvasHeight, final int startColumn)
+ public void drawWrappedPanel(Graphics g, int availWidth, int availHeight,
+ final int startColumn)
{
- int wrappedWidthInResidues = calculateWrappedGeometry(canvasWidth,
- canvasHeight);
+ int wrappedWidthInResidues = calculateWrappedGeometry(availWidth,
+ availHeight);
av.setWrappedWidth(wrappedWidthInResidues);
@@ -560,10 +612,10 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
// we need to call this again to make sure the startColumn +
// wrappedWidthInResidues values are used to calculate wrappedVisibleWidths
// correctly.
- calculateWrappedGeometry(canvasWidth, canvasHeight);
+ calculateWrappedGeometry(availWidth, availHeight);
/*
- * draw one width at a time (including any scales or annotation shown),
+ * draw one width at a time (excluding any scales shown),
* until we have run out of either alignment or vertical space available
*/
int ypos = wrappedSpaceAboveAlignment;
@@ -575,7 +627,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
{
int endColumn = Math
.min(maxWidth, start + wrappedWidthInResidues - 1);
- drawWrappedWidth(g, ypos, start, endColumn, canvasHeight);
+ drawWrappedWidth(g, ypos, start, endColumn, availHeight);
ypos += wrappedRepeatHeightPx;
start += wrappedWidthInResidues;
currentWidth++;
@@ -594,11 +646,11 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
* whether scales are shown left, right or above the alignment
*
*
- * @param canvasWidth
- * @param canvasHeight
+ * @param availWidth
+ * @param availHeight
* @return the number of residue columns in each width
*/
- protected int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
+ protected int calculateWrappedGeometry(int availWidth, int availHeight)
{
int charHeight = av.getCharHeight();
@@ -610,22 +662,30 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
* (av.getScaleAboveWrapped() ? 2 : 1);
/*
- * height in pixels of the wrapped widths
+ * compute height in pixels of the wrapped widths
+ * - start with space above plus sequences
*/
wrappedRepeatHeightPx = wrappedSpaceAboveAlignment;
- // add sequences
- wrappedRepeatHeightPx += av.getRanges().getViewportHeight()
+ wrappedRepeatHeightPx += av.getAlignment().getHeight()
* charHeight;
- // add annotations panel height if shown
- wrappedRepeatHeightPx += getAnnotationHeight();
+
+ /*
+ * add annotations panel height if shown
+ * also gap between sequences and annotations
+ */
+ if (av.isShowAnnotation())
+ {
+ wrappedRepeatHeightPx += getAnnotationHeight();
+ wrappedRepeatHeightPx += SEQS_ANNOTATION_GAP; // 3px
+ }
/*
* number of visible widths (the last one may be part height),
* ensuring a part height includes at least one sequence
*/
ViewportRanges ranges = av.getRanges();
- wrappedVisibleWidths = canvasHeight / wrappedRepeatHeightPx;
- int remainder = canvasHeight % wrappedRepeatHeightPx;
+ wrappedVisibleWidths = availHeight / wrappedRepeatHeightPx;
+ int remainder = availHeight % wrappedRepeatHeightPx;
if (remainder >= (wrappedSpaceAboveAlignment + charHeight))
{
wrappedVisibleWidths++;
@@ -634,7 +694,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
/*
* compute width in residues; this also sets East and West label widths
*/
- int wrappedWidthInResidues = getWrappedCanvasWidth(canvasWidth);
+ int wrappedWidthInResidues = getWrappedCanvasWidth(availWidth);
/*
* limit visibleWidths to not exceed width of alignment
@@ -661,8 +721,9 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
* @param endColumn
* @param canvasHeight
*/
- protected void drawWrappedWidth(Graphics g, int ypos, int startColumn,
- int endColumn, int canvasHeight)
+ protected void drawWrappedWidth(Graphics g, final int ypos,
+ final int startColumn, final int endColumn,
+ final int canvasHeight)
{
ViewportRanges ranges = av.getRanges();
int viewportWidth = ranges.getViewportWidth();
@@ -678,21 +739,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
int xOffset = labelWidthWest
+ ((startColumn - ranges.getStartRes()) % viewportWidth)
* charWidth;
- g.translate(xOffset, 0);
- // When printing we have an extra clipped region,
- // the Printable page which we need to account for here
- Shape clip = g.getClip();
-
- if (clip == null)
- {
- g.setClip(0, 0, viewportWidth * charWidth, canvasHeight);
- }
- else
- {
- g.setClip(0, (int) clip.getBounds().getY(),
- viewportWidth * charWidth, (int) clip.getBounds().getHeight());
- }
+ g.translate(xOffset, 0);
/*
* white fill the region to be drawn (so incremental fast paint doesn't
@@ -709,7 +757,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
if (av.isShowAnnotation())
{
- g.translate(0, cHeight + ypos + 3);
+ final int yShift = cHeight + ypos + SEQS_ANNOTATION_GAP;
+ g.translate(0, yShift);
if (annotations == null)
{
annotations = new AnnotationPanel(av);
@@ -717,9 +766,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
annotations.renderer.drawComponent(annotations, av, g, -1,
startColumn, endx + 1);
- g.translate(0, -cHeight - ypos - 3);
+ g.translate(0, -yShift);
}
- g.setClip(clip);
g.translate(-xOffset, 0);
}
@@ -735,6 +783,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
int charWidth = av.getCharWidth();
g.setFont(av.getFont());
+
g.setColor(Color.black);
int ypos = wrappedSpaceAboveAlignment;
@@ -756,6 +805,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
if (av.getScaleRightWrapped())
{
int x = labelWidthWest + viewportWidth * charWidth;
+
g.translate(x, 0);
drawVerticalScale(g, startCol, endColumn, ypos, false);
g.translate(-x, 0);
@@ -859,13 +909,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
int startx = startRes;
int endx;
int ypos = hgap; // vertical offset
- int maxwidth = av.getAlignment().getWidth();
-
- if (av.hasHiddenColumns())
- {
- maxwidth = av.getAlignment().getHiddenColumns()
- .absoluteToVisibleColumn(maxwidth);
- }
+ int maxwidth = av.getAlignment().getVisibleWidth();
// chop the wrapped alignment extent up into panel-sized blocks and treat
// each block as if it were a block from an unwrapped alignment
@@ -1091,26 +1135,20 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
if (group != null)
{
- g.setColor(group.getOutlineColour());
-
do
{
+ g.setColor(group.getOutlineColour());
drawPartialGroupOutline(g, group, startRes, endRes, startSeq,
endSeq, offset);
groupIndex++;
-
if (groupIndex >= av.getAlignment().getGroups().size())
{
break;
}
-
group = av.getAlignment().getGroups().get(groupIndex);
-
} while (groupIndex < av.getAlignment().getGroups().size());
-
}
-
}
/**
@@ -1456,20 +1494,42 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
* Highlights search results in the visible region by rendering as white text
* on a black background. Any previous highlighting is removed. Answers true
* if any highlight was left on the visible alignment (so status bar should be
+ * set to match), else false. This method does _not_ set the 'fastPaint' flag,
+ * so allows the next repaint to update the whole display.
+ *
+ * @param results
+ * @return
+ */
+ public boolean highlightSearchResults(SearchResultsI results)
+ {
+ return highlightSearchResults(results, false);
+
+ }
+
+ /**
+ * Highlights search results in the visible region by rendering as white text
+ * on a black background. Any previous highlighting is removed. Answers true
+ * if any highlight was left on the visible alignment (so status bar should be
* set to match), else false.
*
- * Currently fastPaint is not implemented for wrapped alignments. If a wrapped
- * alignment had to be scrolled to show the highlighted region, then it should
- * be fully redrawn, otherwise a fast paint can be performed. This argument
- * could be removed if fast paint of scrolled wrapped alignment is coded in
- * future (JAL-2609).
+ * Optionally, set the 'fastPaint' flag for a faster redraw if only the
+ * highlighted regions are modified. This speeds up highlighting across linked
+ * alignments.
+ *
+ * Currently fastPaint is not implemented for scrolled wrapped alignments. If
+ * a wrapped alignment had to be scrolled to show the highlighted region, then
+ * it should be fully redrawn, otherwise a fast paint can be performed. This
+ * argument could be removed if fast paint of scrolled wrapped alignment is
+ * coded in future (JAL-2609).
*
* @param results
- * @param noFastPaint
+ * @param doFastPaint
+ * if true, sets a flag so the next repaint only redraws the modified
+ * image
* @return
*/
public boolean highlightSearchResults(SearchResultsI results,
- boolean noFastPaint)
+ boolean doFastPaint)
{
if (fastpainting)
{
@@ -1478,7 +1538,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
boolean wrapped = av.getWrapAlignment();
try
{
- fastPaint = !noFastPaint;
+ fastPaint = doFastPaint;
fastpainting = fastPaint;
/*
@@ -1535,7 +1595,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
*/
protected boolean drawMappedPositions(SearchResultsI results)
{
- if ((results == null) || (gg == null)) // JAL-2784 check gg is not null
+ if ((results == null) || (img == null)) // JAL-2784 check gg is not null
{
return false;
}
@@ -1607,9 +1667,11 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
}
int transX = (firstCol - ranges.getStartRes()) * av.getCharWidth();
int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight();
+ Graphics gg = img.getGraphics();
gg.translate(transX, transY);
drawPanel(gg, firstCol, lastCol, firstSeq, lastSeq, 0);
gg.translate(-transX, -transY);
+ gg.dispose();
}
return matchFound;
@@ -1620,90 +1682,163 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
{
String eventName = evt.getPropertyName();
- if (eventName.equals(SequenceGroup.SEQ_GROUP_CHANGED))
+ // BH 2019.07.27 removes dead code introduced in aad3650 and simplifies
+ // logic, emphasizing no check for ENDRES or ENDSEQ
+
+ // Both scrolling and resizing change viewport ranges: scrolling changes
+ // both start and end points, but resize only changes end values.
+ // Here we only want to fastpaint on a scroll, with resize using a normal
+ // paint, so scroll events are identified as changes to the horizontal or
+ // vertical start value.
+
+ // Make sure we're not trying to draw a panel
+ // larger than the visible window
+ int scrollX = 0;
+ int scrollY = 0;
+ switch (eventName)
{
+ case SequenceGroup.SEQ_GROUP_CHANGED:
fastPaint = true;
repaint();
return;
- }
- else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
- {
+ case ViewportRanges.MOVE_VIEWPORT:
fastPaint = false;
repaint();
return;
- }
-
- int scrollX = 0;
- if (eventName.equals(ViewportRanges.STARTRES)
- || eventName.equals(ViewportRanges.STARTRESANDSEQ))
- {
- // Make sure we're not trying to draw a panel
- // larger than the visible window
- if (eventName.equals(ViewportRanges.STARTRES))
- {
- scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
- }
- else
+ case ViewportRanges.STARTSEQ:
+ // meaning STARTOREND
+ // typically scroll, but possibly just the end changed
+ fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ return;
+ case ViewportRanges.ENDRES:
+ case ViewportRanges.ENDSEQ:
+ // meaning second event along with "START" -- ENDONLY,NOTSTART
+ // TODO: ignore??
+ return;
+ case ViewportRanges.STARTRES:
+ // meaning STARTOREND
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ break;
+ case ViewportRanges.STARTRESANDSEQ:
+ scrollX = ((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0];
+ scrollY = ((int[]) evt.getNewValue())[1]
+ - ((int[]) evt.getOldValue())[1];
+
+ // System.out.println("SC dx dy " + scrollX + " " + scrollY);
+
+ if (scrollX != 0 && scrollY != 0)
{
- scrollX = ((int[]) evt.getNewValue())[0]
- - ((int[]) evt.getOldValue())[0];
- }
- ViewportRanges vpRanges = av.getRanges();
+ // all sorts of problems in JavaScript if this is commented out.
+ repaint();
+ return;
- int range = vpRanges.getEndRes() - vpRanges.getStartRes();
- if (scrollX > range)
- {
- scrollX = range;
- }
- else if (scrollX < -range)
- {
- scrollX = -range;
}
+ break;
}
- // Both scrolling and resizing change viewport ranges: scrolling changes
- // both start and end points, but resize only changes end values.
- // Here we only want to fastpaint on a scroll, with resize using a normal
- // paint, so scroll events are identified as changes to the horizontal or
- // vertical start value.
- if (eventName.equals(ViewportRanges.STARTRES))
- {
- if (av.getWrapAlignment())
- {
- fastPaintWrapped(scrollX);
- }
- else
- {
- fastPaint(scrollX, 0);
- }
- }
- else if (eventName.equals(ViewportRanges.STARTSEQ))
- {
- // scroll
- fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
- }
- else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
- {
- if (av.getWrapAlignment())
- {
- fastPaintWrapped(scrollX);
- }
- else
- {
- fastPaint(scrollX, 0);
- }
- }
- else if (eventName.equals(ViewportRanges.STARTSEQ))
+
+ ViewportRanges vpRanges = av.getRanges();
+ int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
+ scrollX = Math.max(Math.min(scrollX, range), -range);
+ // only STARTRES or STARTRESANDSEQ:
+ if (av.getWrapAlignment())
{
- // scroll
- fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ fastPaintWrapped(scrollX);
}
- else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ else
{
- if (av.getWrapAlignment())
- {
- fastPaintWrapped(scrollX);
- }
- }
+ fastPaint(scrollX, scrollY);
+ }
+
+ // BH 2019.07.27 was:
+ // if (eventName.equals(SequenceGroup.SEQ_GROUP_CHANGED))
+ // {
+ // fastPaint = true;
+ // repaint();
+ // return;
+ // }
+ // else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
+ // {
+ // fastPaint = false;
+ // // System.err.println("!!!! fastPaint false from MOVE_VIEWPORT");
+ // repaint();
+ // return;
+ // }
+ //
+ // if (eventName.equals(ViewportRanges.STARTRES)
+ // || eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ // {
+ // // Make sure we're not trying to draw a panel
+ // // larger than the visible window
+ // if (eventName.equals(ViewportRanges.STARTRES))
+ // {
+ // scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ // }
+ // else
+ // {
+ // scrollX = ((int[]) evt.getNewValue())[0]
+ // - ((int[]) evt.getOldValue())[0];
+ // }
+ // ViewportRanges vpRanges = av.getRanges();
+ //
+ // int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
+ // if (scrollX > range)
+ // {
+ // scrollX = range;
+ // }
+ // else if (scrollX < -range)
+ // {
+ // scrollX = -range;
+ // }
+ // }
+ // Both scrolling and resizing change viewport ranges: scrolling changes
+ // both start and end points, but resize only changes end values.
+ // Here we only want to fastpaint on a scroll, with resize using a normal
+ // paint, so scroll events are identified as changes to the horizontal or
+ // vertical start value.
+ // BH 2019.07.27 was:
+ // if (eventName.equals(ViewportRanges.STARTRES))
+ // {
+ // if (av.getWrapAlignment())
+ // {
+ // fastPaintWrapped(scrollX);
+ // }
+ // else
+ // {
+ // fastPaint(scrollX, 0);
+ // }
+ // }
+ // else if (eventName.equals(ViewportRanges.STARTSEQ))
+ // {
+ // // scroll
+ // fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ // }
+ // else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ // {
+ // if (av.getWrapAlignment())
+ // {
+ // fastPaintWrapped(scrollX);
+ // }
+ // else
+ // {
+ // fastPaint(scrollX, 0);
+ // }
+ // }
+ //
+ // BH oops!
+ //
+ // else if (eventName.equals(ViewportRanges.STARTSEQ))
+ // {
+ // // scroll
+ // fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ // }
+ // else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ // {
+ // if (av.getWrapAlignment())
+ // {
+ // fastPaintWrapped(scrollX);
+ // }
+ // }
}
/**
@@ -1719,10 +1854,10 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
{
ViewportRanges ranges = av.getRanges();
- if (Math.abs(scrollX) > ranges.getViewportWidth())
+ if (Math.abs(scrollX) >= ranges.getViewportWidth())
{
/*
- * shift of more than one view width is
+ * shift of one view width or more is
* overcomplicated to handle in this method
*/
fastPaint = false;
@@ -1730,7 +1865,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
return;
}
- if (fastpainting || gg == null)
+ if (fastpainting || img == null)
{
return;
}
@@ -1740,6 +1875,9 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
try
{
+
+ Graphics gg = img.getGraphics();
+
calculateWrappedGeometry(getWidth(), getHeight());
/*
@@ -1768,6 +1906,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
*/
drawWrappedDecorators(gg, ranges.getStartRes());
+ gg.dispose();
+
repaint();
} finally
{
@@ -1791,6 +1931,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
return;
}
+ Graphics gg = img.getGraphics();
+
ViewportRanges ranges = av.getRanges();
int viewportWidth = ranges.getViewportWidth();
int charWidth = av.getCharWidth();
@@ -1817,6 +1959,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
/*
* white fill first to erase annotations
*/
+
+
gg.translate(xOffset, 0);
gg.setColor(Color.white);
gg.fillRect(labelWidthWest, ypos,
@@ -1824,6 +1968,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
gg.translate(-xOffset, 0);
drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
+
}
/*
@@ -1867,7 +2012,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
gg.setColor(Color.white);
gg.fillRect(0, canvasHeight - heightBelow, getWidth(), heightBelow);
}
- }
+ gg.dispose();
+ }
/**
* Shifts the visible alignment by the specified number of columns - left if
@@ -1883,6 +2029,9 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
{
return;
}
+
+ Graphics gg = img.getGraphics();
+
int charWidth = av.getCharWidth();
int canvasHeight = getHeight();
@@ -1913,10 +2062,17 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
while (y >= 0)
{
+ /*
+ * shift 'widthToCopy' residues by 'positions' places to the right
+ */
gg.copyArea(copyFromLeftStart, y, widthToCopy, heightToCopy,
positions * charWidth, 0);
if (y > 0)
{
+ /*
+ * copy 'positions' residue from the row above (right hand end)
+ * to this row's left hand end
+ */
gg.copyArea(copyFromRightStart, y - wrappedRepeatHeightPx,
positions * charWidth, heightToCopy, -widthToCopy,
wrappedRepeatHeightPx);
@@ -1949,11 +2105,11 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
* charWidth, heightToCopy, widthToCopy,
-wrappedRepeatHeightPx);
}
-
y += wrappedRepeatHeightPx;
xpos += viewportWidth;
}
}
+ gg.dispose();
}
@@ -1969,7 +2125,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
*/
protected boolean drawMappedPositionsWrapped(SearchResultsI results)
{
- if ((results == null) || (gg == null)) // JAL-2784 check gg is not null
+ if ((results == null) || (img == null)) // JAL-2784 check gg is not null
{
return false;
}
@@ -2004,6 +2160,9 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
int gapHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
+
+ Graphics gg = img.getGraphics();
+
for (int seqNo = ranges.getStartSeq(); seqNo <= ranges
.getEndSeq(); seqNo++)
{
@@ -2074,6 +2233,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
}
}
+ gg.dispose();
+
return matchFound;
}
@@ -2086,4 +2247,5 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
{
return labelWidthWest;
}
+
}