-
Notifications
You must be signed in to change notification settings - Fork 53
Closed
Description
Consider the following snippet:
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.FlowLayout;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
public class ScrollingBug {
public static void main(String[] args) {
System.setProperty("swt.autoScale.updateOnRuntime", "true");
Shell shell = new Shell();
shell.setSize(400, 400);
shell.setLayout(new FillLayout());
FigureCanvas canvas = new FigureCanvas(shell, SWT.NONE);
Figure root = new Figure();
root.setLayoutManager(new ListLayout());
root.add(createLabel(ColorConstants.red));
root.add(createLabel(ColorConstants.green));
root.add(createLabel(ColorConstants.blue));
root.add(createLabel(ColorConstants.yellow));
root.add(createLabel(ColorConstants.cyan));
root.add(createLabel(ColorConstants.white));
root.add(createLabel(ColorConstants.gray));
root.add(createLabel(ColorConstants.orange));
canvas.getViewport().setContentsTracksHeight(true);
canvas.getViewport().setContentsTracksWidth(true);
canvas.getViewport().setContents(root);
shell.open();
Display display = shell.getDisplay();
while (!display.isDisposed()) {
display.readAndDispatch();
}
}
private static IFigure createLabel(Color bg) {
return new Figure() {
@Override
protected void paintFigure(Graphics graphics) {
super.paintFigure(graphics);
graphics.setBackgroundColor(bg);
graphics.fillRectangle(getClientArea());
}
@Override
public Dimension getPreferredSize(int wHint, int hHint) {
return new Dimension(wHint, 100);
}
};
}
private static class ListLayout extends FlowLayout {
public ListLayout() {
setMajorSpacing(0);
}
}
}
To reproduce:
- Launch the snippet on a system with > 100% zoom (in my case 150%)
- Scroll the shell down to the bottom
- Scroll the shell up to the top
What I expect:
The first line should be 150px tall.
What I get:
The first line is 154px tall.
The left shell is the original one with the 150px tall row, the right shell the one after scrolling with 154px.

Workaround:
Clicking on the canvas corrects the sizes for all figures. For non-trivial figures, this causes glitches and other visual artifacts. As a more "permanent" solution, one can hook a PropertyChangeListener
to the scrollbar of the Viewport
, that requests a repaint of the root figure, whenever the value changes.