X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fgui%2FSeqCanvas.java;h=11371531549941169b306f1e84e1cf7c235972f8;hb=d043ce47fc710d3eb2629ba926a8a7417bd67d8c;hp=ac7cf1007f8d1d080cd05cca7d138976f1ae3319;hpb=57738a1f3c19b1c3a00bd3ac5108f8cd0af32f99;p=jalview.git
diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java
index ac7cf10..1137153 100755
--- a/src/jalview/gui/SeqCanvas.java
+++ b/src/jalview/gui/SeqCanvas.java
@@ -76,7 +76,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
private final SequenceRenderer seqRdr;
- boolean fastPaint = false;
+ private boolean fastPaint = false;
private boolean fastpainting = false;
@@ -95,6 +95,11 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
private int wrappedVisibleWidths; // number of wrapped widths displayed
+ private int availWidth;
+
+ private int availHeight;
+
+ private boolean allowFastPaint;
// Don't do this! Graphics handles are supposed to be transient
// private Graphics2D gg;
@@ -203,7 +208,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
int yPos = ypos + charHeight;
int startX = startx;
int endX = endx;
-
+
if (av.hasHiddenColumns())
{
HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
@@ -343,6 +348,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
}
+
// System.err.println(">>> FastPaint to " + transX + " " + transY + " "
// + horizontal + " " + vertical + " " + startRes + " " + endRes
// + " " + startSeq + " " + endSeq);
@@ -352,7 +358,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
img.getWidth(), img.getHeight(), -horizontal * charWidth,
-vertical * charHeight);
- /** @j2sNative xxi = this.img */
gg.translate(transX, transY);
drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
@@ -362,7 +367,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
// 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
{
@@ -373,19 +377,14 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
@Override
public void paintComponent(Graphics g)
{
+ if (av.getAlignPanel().getHoldRepaint())
+ {
+ return;
+ }
- int charHeight = av.getCharHeight();
- int charWidth = av.getCharWidth();
-
- int width = getWidth();
- int height = getHeight();
-
- width -= (width % charWidth);
- height -= (height % charHeight);
-
- // BH 2019 can't possibly fastPaint if either width or height is 0
+ getAvailSizes();
- if (width == 0 || height == 0)
+ if (availWidth == 0 || availHeight == 0)
{
return;
}
@@ -419,11 +418,9 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
// }
Rectangle vis, clip;
- if (img != null
- && (fastPaint
- || (vis = getVisibleRect()).width != (clip = g
- .getClipBounds()).width
- || vis.height != clip.height))
+ if (allowFastPaint && img != null
+ && (fastPaint || (vis = getVisibleRect()).width != (clip = g.getClipBounds()).width
+ || vis.height != clip.height))
{
g.drawImage(img, 0, 0, this);
drawSelectionGroup((Graphics2D) g, startRes, endRes, startSeq,
@@ -432,13 +429,15 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
else
{
+ allowFastPaint = true;
// 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 || width != img.getWidth()
- || height != img.getHeight())
+ if (img == null || availWidth != img.getWidth()
+ || availHeight != img.getHeight())
{
- img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ img = new BufferedImage(availWidth, availHeight,
+ BufferedImage.TYPE_INT_RGB);
}
Graphics2D gg = (Graphics2D) img.getGraphics();
@@ -451,11 +450,11 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
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
{
@@ -473,7 +472,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
drawCursor(g, startRes, endRes, startSeq, endSeq);
}
}
-
/**
* Draw an alignment panel for printing
*
@@ -537,7 +535,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
FontMetrics fm = getFontMetrics(av.getFont());
int labelWidth = 0;
-
+
if (av.getScaleRightWrapped() || av.getScaleLeftWrapped())
{
labelWidth = getLabelWidth(fm);
@@ -573,6 +571,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
maxWidth = Math.max(maxWidth, alignment.getSequenceAt(i).getEnd());
}
+ // quick int log10
int length = 0;
for (int i = maxWidth; i > 0; i /= 10)
{
@@ -587,18 +586,17 @@ public class SeqCanvas extends JPanel 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();
av.setWrappedWidth(wrappedWidthInResidues);
@@ -608,7 +606,7 @@ public class SeqCanvas extends JPanel 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();
/*
* draw one width at a time (excluding any scales shown),
@@ -623,7 +621,7 @@ public class SeqCanvas extends JPanel 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++;
@@ -632,6 +630,15 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
drawWrappedDecorators(g, startColumn);
}
+ private void getAvailSizes()
+ {
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+ availWidth = getWidth();
+ availHeight = getHeight();
+ availWidth -= (availWidth % charWidth);
+ availHeight -= (availHeight % charHeight);
+ }
/**
* Calculates and saves values needed when rendering a wrapped alignment.
* These depend on many factors, including
@@ -642,11 +649,24 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
*
whether scales are shown left, right or above the alignment
*
*
+ * @param availWidth
+ * @param availHeight
+ * @return the number of residue columns in each width
+ */
+ protected int calculateWrappedGeometry()
+ {
+ getAvailSizes();
+ return calculateWrappedGeometry(availWidth, availHeight);
+
+ }
+
+ /**
+ * for test only
* @param canvasWidth
* @param canvasHeight
- * @return the number of residue columns in each width
+ * @return
*/
- protected int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
+ public int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
{
int charHeight = av.getCharHeight();
@@ -661,8 +681,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
* compute height in pixels of the wrapped widths
* - start with space above plus sequences
*/
- wrappedRepeatHeightPx = wrappedSpaceAboveAlignment;
- wrappedRepeatHeightPx += av.getAlignment().getHeight() * charHeight;
+ wrappedRepeatHeightPx = wrappedSpaceAboveAlignment
+ + av.getAlignment().getHeight() * charHeight;
/*
* add annotations panel height if shown
@@ -800,7 +820,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
if (av.getScaleRightWrapped())
{
int x = labelWidthWest + viewportWidth * charWidth;
-
g.translate(x, 0);
drawVerticalScale(g, startCol, endColumn, ypos, false);
g.translate(-x, 0);
@@ -881,6 +900,11 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
}
+ private final static BasicStroke dottedStroke = new BasicStroke(1,
+ BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 3f, new float[]
+ { 5f, 3f }, 0f);
+
+ private final static BasicStroke basicStroke = new BasicStroke();
/*
* Draw a selection group over a wrapped alignment
*/
@@ -889,9 +913,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
{
// chop the wrapped alignment extent up into panel-sized blocks and treat
// each block as if it were a block from an unwrapped alignment
- g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
- BasicStroke.JOIN_ROUND, 3f, new float[]
- { 5f, 3f }, 0f));
+ g.setStroke(dottedStroke);
g.setColor(Color.RED);
int charWidth = av.getCharWidth();
@@ -899,6 +921,20 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
/ charWidth;
int startx = startRes;
int maxwidth = av.getAlignment().getVisibleWidth();
+ // JAL-3253-applet had this:
+ // // height gap above each panel
+ // int charHeight = av.getCharHeight();
+ // int hgap = charHeight;
+ // if (av.getScaleAboveWrapped())
+ // {
+ // hgap += charHeight;
+ // }
+ // int dy = getAnnotationHeight() + hgap
+ // + av.getAlignment().getHeight() * charHeight;
+ // int ypos = hgap; // vertical offset
+
+ // this is from 0b573ed (gmungoc)
+ int dy = wrappedRepeatHeightPx;
int ypos = wrappedSpaceAboveAlignment;
while ((ypos <= canvasHeight) && (startx < maxwidth))
@@ -916,11 +952,13 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
av.getAlignment().getHeight() - 1, ypos);
g.translate(-labelWidthWest, 0);
- ypos += wrappedRepeatHeightPx;
+ // update vertical offset
+ ypos += dy;
+ // update horizontal offset
startx += cWidth;
}
- g.setStroke(new BasicStroke());
+ g.setStroke(basicStroke);
}
/**
@@ -1257,6 +1295,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
}
+
/**
* Draw a selection group over an unwrapped alignment
*
@@ -1279,7 +1318,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
int startRes, int endRes, int startSeq, int endSeq, int offset)
{
int charWidth = av.getCharWidth();
-
if (!av.hasHiddenColumns())
{
drawPartialGroupOutline(g, group, startRes, endRes, startSeq, endSeq,
@@ -1472,7 +1510,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
g.drawLine(sx + xwidth, oldY, sx + xwidth, sy);
}
}
-
/**
* Highlights search results in the visible region by rendering as white text
* on a black background. Any previous highlighting is removed. Answers true
@@ -1488,7 +1525,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
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
@@ -1665,92 +1701,157 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
public void propertyChange(PropertyChangeEvent evt)
{
String eventName = evt.getPropertyName();
- // System.err.println(">>SeqCanvas propertyChange " + eventName);
- 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;
- // System.err.println("!!!! fastPaint false from MOVE_VIEWPORT");
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.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];
+ 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() + 1;
- if (scrollX > range)
- {
- scrollX = range;
- }
- else if (scrollX < -range)
- {
- scrollX = -range;
}
+ break;
+ default:
+ return;
}
+
+ 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())
+ {
+ fastPaintWrapped(scrollX);
+ }
+ else
+ {
+ 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.
- 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))
- {
- // scroll
- fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
- }
- else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
- {
- if (av.getWrapAlignment())
- {
- fastPaintWrapped(scrollX);
- }
- }
+ // 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);
+ // }
+ // }
}
/**
@@ -1787,10 +1888,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
try
{
-
Graphics gg = img.getGraphics();
-
- calculateWrappedGeometry(getWidth(), getHeight());
+ calculateWrappedGeometry();
/*
* relocate the regions of the alignment that are still visible
@@ -1819,7 +1918,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
drawWrappedDecorators(gg, ranges.getStartRes());
gg.dispose();
-
repaint();
} finally
{
@@ -1844,7 +1942,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
Graphics gg = img.getGraphics();
-
ViewportRanges ranges = av.getRanges();
int viewportWidth = ranges.getViewportWidth();
int charWidth = av.getCharWidth();
@@ -1872,7 +1969,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
/*
* white fill first to erase annotations
*/
-
gg.translate(xOffset, 0);
gg.setColor(Color.white);
gg.fillRect(labelWidthWest, ypos, (endRes - startRes + 1) * charWidth,
@@ -1880,7 +1976,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
gg.translate(-xOffset, 0);
drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
-
}
/*
@@ -2044,7 +2139,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
boolean matchFound = false;
- calculateWrappedGeometry(getWidth(), getHeight());
+ calculateWrappedGeometry();
int wrappedWidth = av.getWrappedWidth();
int wrappedHeight = wrappedRepeatHeightPx;
@@ -2142,7 +2237,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
}
}
-
gg.dispose();
return matchFound;
@@ -2158,4 +2252,13 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
return labelWidthWest;
}
+ /**
+ * Clears the flag that allows a 'fast paint' on the next repaint, so
+ * requiring a full repaint
+ */
+ public void setNoFastPaint()
+ {
+ allowFastPaint = false;
+ }
+
}