@Override
public void scrollTopChanged(Viewport viewport, int previousScrollTop) {
// NOTE we don't invalidate the component here because we need only
// reposition the view and row header. Invalidating would yield
// the correct positioning, but it would do much more work than needed.
ScrollPane scrollPane = (ScrollPane)viewport;
Component view = scrollPane.getView();
Component rowHeader = scrollPane.getRowHeader();
Component columnHeader = scrollPane.getColumnHeader();
int columnHeaderHeight = 0;
if (columnHeader != null) {
columnHeaderHeight = columnHeader.getHeight();
}
int scrollTop = scrollPane.getScrollTop();
if (view != null
&& view.isShowing()
&& isOptimizeScrolling()) {
Bounds blitArea = view.getVisibleArea();
int blitX = blitArea.x + view.getX();
int blitY = blitArea.y + view.getY();
int blitWidth = blitArea.width;
int blitHeight = blitArea.height;
if (rowHeader != null) {
// Blit the row header as well
int rowHeaderWidth = rowHeader.getWidth();
blitX -= rowHeaderWidth;
blitWidth += rowHeaderWidth;
}
int deltaScrollTop = scrollTop - previousScrollTop;
blitY += Math.max(deltaScrollTop, 0);
blitHeight -= Math.abs(deltaScrollTop);
Graphics2D graphics = scrollPane.getGraphics();
graphics.copyArea(blitX, blitY, blitWidth, blitHeight, 0, -deltaScrollTop);
scrollPane.setConsumeRepaint(true);
try {
view.setLocation(view.getX(), columnHeaderHeight - scrollTop);
if (rowHeader != null) {
rowHeader.setLocation(0, columnHeaderHeight - scrollTop);
}
} finally {
scrollPane.setConsumeRepaint(false);
}
boolean repaintAllViewport = scrollPane.isRepaintAllViewport();
if (!repaintAllViewport) {
scrollPane.repaint(blitX, (columnHeaderHeight + (deltaScrollTop > 0 ? blitHeight : 0)),
blitWidth, Math.abs(deltaScrollTop), true);
} else {
Bounds viewportBounds = getViewportBounds();
scrollPane.repaint(viewportBounds.x, viewportBounds.y,
viewportBounds.width, viewportBounds.height, true);
}
} else {
if (view != null) {