public static void main(String[] args) {
	final Display display = new Display();
	Shell shell = new Shell(display);
	shell.setLayout(new FillLayout());
	final Tree tree = new Tree(shell, SWT.FULL_SELECTION | SWT.BORDER);
	tree.setHeaderVisible(true);
	TreeColumn column0 = new TreeColumn(tree, SWT.LEFT);
	column0.setText("Column 0");
	TreeColumn column1 = new TreeColumn(tree, SWT.LEFT);
	column1.setText("Column 1");
	TreeColumn column2 = new TreeColumn(tree, SWT.LEFT);
	column2.setText("Column 2");
	for (int i = 0; i < 9; i++) {
		TreeItem item = new TreeItem(tree, SWT.NONE);
		item.setText("item "+i);
		item.setText(1, "column 1 - "+i);
		item.setText(2, "column 2 - "+i);
		for (int j = 0; j < 9; j++) {
			TreeItem subItem = new TreeItem(item, SWT.NONE);
			subItem.setText("item "+i+" "+j);
			subItem.setText(1, "column 1 - "+i+" "+j);
			subItem.setText(2, "column 2 - "+i+" "+j);
			for (int k = 0; k < 9; k++) {
				TreeItem subsubItem = new TreeItem(subItem, SWT.NONE);
				subsubItem.setText("item "+i+" "+j+" "+k);
				subsubItem.setText(1, "column 1 - "+i+" "+j+" "+k);
				subsubItem.setText(2, "column 2 - "+i+" "+j+" "+k);
			}
		}
	}
	column0.pack();
	column1.pack();
	column2.pack();
	
	Heartbeat = new Runnable() {
		@Override
		public void run() {
			if (!Tracking || tree.isDisposed()) return;
			Point cursor = display.getCursorLocation();
			cursor = display.map(null, tree, cursor);
			Scroll(tree, cursor.x, cursor.y);
			display.timerExec(ScrollSpeed, Heartbeat);
		}
	};
	Listener listener = new Listener() {
		@Override
		public void handleEvent(Event event) {
			switch (event.type) {
			case SWT.MouseEnter:
				Tracking = true;
				display.timerExec(0, Heartbeat);
				break;
			case SWT.MouseExit:
				Tracking = false;
				break;
			}
		}
	};
	tree.addListener(SWT.MouseEnter, listener); 
	tree.addListener(SWT.MouseExit, listener);
	shell.open();
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch())
			display.sleep();
	}
	display.dispose();
}