DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Ivor has posted 7 posts at DZone. View Full User Profile

Java:SWT: Scrolled Composite Autoscroll Adapter

02.21.2009
| 1656 views |
  • submit to reddit
        Java:SWT: scrolled composite autoscroll adapter

<s>Something very similar was implemented in ScrolledComposite in 3.4.</s>
Slightly revised code from the 3.4 version has now been used.

package ca.freewill.swtbot;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

public class AutoScrollAdapter {
	
	private final ScrolledComposite scrolledComposite;

	public AutoScrollAdapter(ScrolledComposite scrolledComposite) {
		this.scrolledComposite = scrolledComposite;
		scrolledComposite.getDisplay().addFilter(SWT.FocusIn, new Listener() {
			public void handleEvent(Event event) {
				handleWidget(event);
			}
		});
		Control control = scrolledComposite.getDisplay().getFocusControl();
		handleControl(control);
	}
	
	private void handleWidget(Event event) {
		if (event.widget instanceof Control) {
			handleControl((Control) event.widget);
		}
	}

	private void handleControl(Control control) {
		if (scrolledCompositeContains(control)) {
			showControl(control);
		}
	}

	private boolean scrolledCompositeContains(Control control) {
		if (control == null || control.isDisposed()) return false;

		for (Composite parent = control.getParent(); parent != null; parent = parent.getParent()) {
			if (parent instanceof Shell) return false;
			if (parent == scrolledComposite) return true;
		}
		
		return false;
	}

	private void showControl(Control control) {
		Rectangle itemRect = scrolledComposite.getDisplay().map(control.getParent(), scrolledComposite, control.getBounds());
		Rectangle area = scrolledComposite.getClientArea();
		Point origin = scrolledComposite.getOrigin();
		if (itemRect.x < 0) origin.x = Math.max(0, origin.x + itemRect.x);
		if (itemRect.y < 0) origin.y = Math.max(0, origin.y + itemRect.y);
		if (area.width < itemRect.x + itemRect.width) origin.x = Math.max(0, origin.x + itemRect.x + itemRect.width - area.width);
		if (area.height < itemRect.y + itemRect.height) origin.y = Math.max(0, origin.y + itemRect.y + itemRect.height - area.height);
		scrolledComposite.setOrigin(origin);
	}

}