Не уверен, что вы уже поняли это, но проблема в том, что ScrolledComposite всегда устанавливает содержимое в 0/0, когда оно изменяется. Я не уверен, почему ваш подход работает на OS X, и я не проверял мой пример, поскольку у меня нет Mac здесь.
Решение состоит в том, чтобы использовать композитный наполнитель, который всегда по крайней мере такой же большой, как клиентская область из ScrolledComposite. В этом наполнителе вы можете правильно центрировать холст.
Я привел небольшой пример, в качестве дополнительного бонуса он также центрирует холст, если клиентская область SC меньше, чем холст (потому что я сначала подумал, что это был ваш вопрос :))
Возможно, вам придется внести некоторые незначительные изменения, я думаю, что в OS X есть некоторые глюки с этим кодом ...
package test;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Test {
public static void main(final String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout( new FillLayout() );
final ScrolledComposite sComp = new ScrolledComposite( shell, SWT.H_SCROLL | SWT.V_SCROLL );
final Composite fillComp = new Composite( sComp, SWT.NONE );
sComp.setLayout( new FillLayout() );
final Canvas c = new Canvas( fillComp, SWT.DOUBLE_BUFFERED );
c.addPaintListener( new PaintListener() {
public void paintControl(PaintEvent e) {
Point p = c.getSize();
e.gc.setBackground( display.getSystemColor( SWT.COLOR_RED ));
e.gc.fillRectangle( 0, 0, p.x, p.y );
e.gc.setBackground( display.getSystemColor( SWT.COLOR_BLUE ));
e.gc.fillRectangle( p.x / 2 - 10, p.y / 2 - 10, 20, 20 );
}
});
c.setSize( 400, 400 );
sComp.setContent( fillComp );
sComp.addControlListener( new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
Rectangle clientArea = sComp.getClientArea();
Point cSize = c.getSize();
int fillX = Math.max( clientArea.width, cSize.x );
int fillY = Math.max( clientArea.height, cSize.y );
fillComp.setSize( fillX, fillY );
int cX = ( clientArea.width - cSize.x ) / 2;
int cY = ( clientArea.height - cSize.y ) / 2;
sComp.setOrigin( -cX, -cY );
int locX = Math.max( cX, 0 );
int locY = Math.max( cY, 0 );
c.setLocation( locX, locY );
}
});
shell.open();
shell.pack();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}