import jalview.datamodel.SearchResultsI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.datamodel.VisibleContigsIterator;
import jalview.renderer.ScaleRenderer;
import jalview.renderer.ScaleRenderer.ScaleMark;
import jalview.util.Comparison;
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;
if (av.hasHiddenColumns())
{
HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
- startX = hiddenColumns.adjustForHiddenColumns(startx);
- endX = hiddenColumns.adjustForHiddenColumns(endx);
+ startX = hiddenColumns.visibleToAbsoluteColumn(startx);
+ endX = hiddenColumns.visibleToAbsoluteColumn(endx);
}
FontMetrics fm = getFontMetrics(av.getFont());
int endSeq = ranges.getEndSeq();
int transX = 0;
int transY = 0;
-
+
gg.copyArea(horizontal * charWidth, vertical * charHeight,
img.getWidth(), img.getHeight(), -horizontal * charWidth,
-vertical * charHeight);
drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
gg.translate(-transX, -transY);
- repaint();
+ // 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.
+ av.getAlignPanel().repaint();
} finally
{
fastpainting = false;
int charHeight = av.getCharHeight();
int charWidth = av.getCharWidth();
-
+
ViewportRanges ranges = av.getRanges();
-
+
int width = getWidth();
int height = getHeight();
-
+
width -= (width % charWidth);
height -= (height % charHeight);
-
+
// selectImage is the selection group outline image
BufferedImage selectImage = drawSelectionGroup(
ranges.getStartRes(), ranges.getEndRes(),
ranges.getStartSeq(), ranges.getEndSeq());
-
+
if ((img != null) && (fastPaint
|| (getVisibleRect().width != g.getClipBounds().width)
|| (getVisibleRect().height != g.getClipBounds().height)))
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());
-
+
if (av.getWrapAlignment())
{
drawWrappedPanel(gg, getWidth(), getHeight(), ranges.getStartRes());
drawPanel(gg, ranges.getStartRes(), ranges.getEndRes(),
ranges.getStartSeq(), ranges.getEndSeq(), 0);
}
-
+
// lcimg is a local *copy* of img which we'll draw selectImage on top of
BufferedImage lcimg = buildLocalImage(selectImage);
g.drawImage(lcimg, 0, 0, this);
private BufferedImage buildLocalImage(BufferedImage selectImage)
{
// clone the cached image
- BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(),
- img.getType());
+ BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(),
+ img.getType());
+
+ // BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(),
+ // img.getType());
Graphics2D g2d = lcimg.createGraphics();
g2d.drawImage(img, 0, 0, null);
try
{
- lcimg = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_ARGB); // ARGB so alpha compositing works
+ lcimg = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_ARGB); // ARGB so alpha compositing works
} catch (OutOfMemoryError er)
{
System.gc();
* white fill the region to be drawn (so incremental fast paint doesn't
* scribble over an existing image)
*/
- gg.setColor(Color.white);
- gg.fillRect(0, ypos, (endx - startColumn + 1) * charWidth,
+ g.setColor(Color.white);
+ g.fillRect(0, ypos, (endx - startColumn + 1) * charWidth,
wrappedRepeatHeightPx);
drawPanel(g, startColumn, endx, 0, av.getAlignment().getHeight() - 1,
int charWidth = av.getCharWidth();
g.setColor(Color.blue);
+ int res;
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- List<Integer> positions = hidden.findHiddenRegionPositions();
- for (int pos : positions)
+
+ Iterator<Integer> it = hidden.getStartRegionIterator(startColumn,
+ endColumn);
+ while (it.hasNext())
{
- int res = pos - startColumn;
+ res = it.next() - startColumn;
if (res < 0 || res > endColumn - startColumn + 1)
{
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth);
+ .absoluteToVisibleColumn(maxwidth);
}
// chop the wrapped alignment extent up into panel-sized blocks and treat
else
{
int screenY = 0;
- final int screenYMax = endRes - startRes;
- int blockStart = startRes;
- int blockEnd = endRes;
+ int blockStart;
+ int blockEnd;
- for (int[] region : av.getAlignment().getHiddenColumns()
- .getHiddenColumnsCopy())
- {
- int hideStart = region[0];
- int hideEnd = region[1];
+ HiddenColumns hidden = av.getAlignment().getHiddenColumns();
+ VisibleContigsIterator regions = hidden
+ .getVisContigsIterator(startRes, endRes + 1, true);
- if (hideStart <= blockStart)
- {
- blockStart += (hideEnd - hideStart) + 1;
- continue;
- }
+ while (regions.hasNext())
+ {
+ int[] region = regions.next();
+ blockEnd = region[1];
+ blockStart = region[0];
/*
* draw up to just before the next hidden region, or the end of
* the visible region, whichever comes first
*/
- blockEnd = Math.min(hideStart - 1, blockStart + screenYMax
- - screenY);
-
g1.translate(screenY * charWidth, 0);
draw(g1, blockStart, blockEnd, startSeq, endSeq, yOffset);
* draw the downline of the hidden column marker (ScalePanel draws the
* triangle on top) if we reached it
*/
- if (av.getShowHiddenMarkers() && blockEnd == hideStart - 1)
+ if (av.getShowHiddenMarkers()
+ && (regions.hasNext() || regions.endsAtHidden()))
{
g1.setColor(Color.blue);
g1.translate(-screenY * charWidth, 0);
screenY += blockEnd - blockStart + 1;
- blockStart = hideEnd + 1;
-
- if (screenY > screenYMax)
- {
- // already rendered last block
- return;
- }
- }
-
- if (screenY <= screenYMax)
- {
- // remaining visible region to render
- blockEnd = blockStart + screenYMax - screenY;
- g1.translate(screenY * charWidth, 0);
- draw(g1, blockStart, blockEnd, startSeq, endSeq, yOffset);
-
- g1.translate(-screenY * charWidth, 0);
}
}
if (av.hasSearchResults())
{
SearchResultsI searchResults = av.getSearchResults();
- int[] visibleResults = searchResults.getResults(nextSeq,
- startRes, endRes);
+ int[] visibleResults = searchResults.getResults(nextSeq, startRes,
+ endRes);
if (visibleResults != null)
{
for (int r = 0; r < visibleResults.length; r += 2)
{
seqRdr.drawHighlightedText(nextSeq, visibleResults[r],
- visibleResults[r + 1], (visibleResults[r] - startRes)
- * charWidth, offset
- + ((i - startSeq) * charHeight));
+ visibleResults[r + 1],
+ (visibleResults[r] - startRes) * charWidth,
+ offset + ((i - startSeq) * charHeight));
}
}
}
// convert the cursorX into a position on the visible alignment
int cursor_xpos = av.getAlignment().getHiddenColumns()
- .findColumnPosition(cursorX);
+ .absoluteToVisibleColumn(cursorX);
if (av.getAlignment().getHiddenColumns().isVisible(cursorX))
{
{
// package into blocks of visible columns
int screenY = 0;
- int blockStart = startRes;
- int blockEnd = endRes;
+ int blockStart;
+ int blockEnd;
- for (int[] region : av.getAlignment().getHiddenColumns()
- .getHiddenColumnsCopy())
+ HiddenColumns hidden = av.getAlignment().getHiddenColumns();
+ VisibleContigsIterator regions = hidden
+ .getVisContigsIterator(startRes, endRes + 1, true);
+ while (regions.hasNext())
{
- int hideStart = region[0];
- int hideEnd = region[1];
-
- if (hideStart <= blockStart)
- {
- blockStart += (hideEnd - hideStart) + 1;
- continue;
- }
-
- blockEnd = hideStart - 1;
+ int[] region = regions.next();
+ blockEnd = region[1];
+ blockStart = region[0];
g.translate(screenY * charWidth, 0);
drawPartialGroupOutline(g, group,
g.translate(-screenY * charWidth, 0);
screenY += blockEnd - blockStart + 1;
- blockStart = hideEnd + 1;
-
- if (screenY > (endRes - startRes))
- {
- // already rendered last block
- break;
- }
- }
-
- if (screenY <= (endRes - startRes))
- {
- // remaining visible region to render
- blockEnd = blockStart + (endRes - startRes) - screenY;
- g.translate(screenY * charWidth, 0);
- drawPartialGroupOutline(g, group,
- blockStart, blockEnd, startSeq, endSeq, offset);
-
- g.translate(-screenY * charWidth, 0);
}
}
}
*/
protected boolean drawMappedPositions(SearchResultsI results)
{
- if (results == null)
+ if ((results == null) || (gg == null)) // JAL-2784 check gg is not null
{
return false;
}
if (av.hasHiddenColumns())
{
firstVisibleColumn = alignment.getHiddenColumns()
- .adjustForHiddenColumns(firstVisibleColumn);
+ .visibleToAbsoluteColumn(firstVisibleColumn);
lastVisibleColumn = alignment.getHiddenColumns()
- .adjustForHiddenColumns(lastVisibleColumn);
+ .visibleToAbsoluteColumn(lastVisibleColumn);
}
for (int seqNo = ranges.getStartSeq(); seqNo <= ranges
if (av.hasHiddenColumns())
{
firstCol = alignment.getHiddenColumns()
- .findColumnPosition(firstCol);
- lastCol = alignment.getHiddenColumns().findColumnPosition(lastCol);
+ .absoluteToVisibleColumn(firstCol);
+ lastCol = alignment.getHiddenColumns().absoluteToVisibleColumn(lastCol);
}
int transX = (firstCol - ranges.getStartRes()) * av.getCharWidth();
int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight();
{
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
{
fastPaint(scrollX, 0);
}
- // bizarrely, we only need to scroll on the x value here as fastpaint
- // copies the full height of the image anyway. Passing in the y value
- // causes nasty repaint artefacts, which only disappear on a full
- // repaint.
+ }
+ 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);
}
}
}
{
ViewportRanges ranges = av.getRanges();
- // if (Math.abs(scrollX) > ranges.getViewportWidth())
- // JAL-2836, 2836 temporarily removed wrapped fastpaint for release 2.10.3
- if (true)
+ if (Math.abs(scrollX) > ranges.getViewportWidth())
{
/*
* shift of more than one view width is
*/
protected boolean drawMappedPositionsWrapped(SearchResultsI results)
{
- if (results == null)
+ if ((results == null) || (gg == null)) // JAL-2784 check gg is not null
{
return false;
}
if (av.hasHiddenColumns())
{
firstVisibleColumn = alignment.getHiddenColumns()
- .adjustForHiddenColumns(firstVisibleColumn);
+ .visibleToAbsoluteColumn(firstVisibleColumn);
lastVisibleColumn = alignment.getHiddenColumns()
- .adjustForHiddenColumns(lastVisibleColumn);
+ .visibleToAbsoluteColumn(lastVisibleColumn);
}
int gapHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
if (av.hasHiddenColumns())
{
displayColumn = alignment.getHiddenColumns()
- .findColumnPosition(displayColumn);
+ .absoluteToVisibleColumn(displayColumn);
}
/*