使用Tab键实现表格的跳转

在Excel中,如果按Tab键,则焦点会在相邻的方格中不断的跳转。

 

在SWT的Table或TableTree中,缺省情况下,是不支持这种通过Tab键的跳转的。如果能实现一个这样的功能,是不是很酷?

 

好,这里就教你这一招的实现,使用EditingSupport可以很容易的实现这个功能。

 

这里假设你实现的是一棵树表,并且这个树表要求至少包含SWT.FULL_SELECTION的样式。要求含Full_Selection样子主要是为了实现方便,因为full_selection样式支持鼠标在任意位置对表格的选中,否则只有在被选择行的表格才能被选中。

 

假如这个树已经通过增加EditingSupport实现了编辑支持。下面就是实现Tab键的跳转,实现如下:

 

思路:如果通过点击鼠标,很容易就让CellEditor出现,所以要实现Tab,我们可以通过模拟鼠标点击事件来实现。在SWT中,有两种实现模拟事件的方式,一种是通过Display的post()方法来实现,另一个是widget的notifyListener()方法来实现。这里我要用的notifyListener()。

 

首先给CellEditor的Control增加监听,如下:

cellEditor.getControl().addTraverseListener(this);

 

这里我记EditingSupport实现了TraverseListener,如下:

class FileEditingSupport extends EditingSupport implements TraverseListener

 

最后就是实现keyTraverse()方法,用来模拟鼠标事件:

 

	public void keyTraversed(TraverseEvent e) {
		if(e.character!=SWT.TAB){
			return;
		}
		Rectangle bound = cellEditor.getControl().getBounds();
		Tree tree = (Tree) getViewer().getControl();
		
		int x = bound.x+bound.width+2;
		int y = bound.y;
		if(index==tree.getColumnCount()-1){
			x = tree.getColumn(0).getWidth()-2;
			y = y+bound.height+2;
		}
		
		Event origin = new Event();
		origin.widget = tree;
		origin.x = x;
		origin.y = y;
		origin.display = tree.getDisplay();
		origin.time = e.time;
		origin.count = 1;
		origin.type = SWT.MouseDown;
		origin.button = 1;
		
		tree.notifyListeners(SWT.MouseDown, origin);
	} 

 

对于普通的TextCellEditor和ComboCellEditor,这样做是没什么问题的。不过如果你有一个DialogCellEditor,你就发现失灵的。这是因为DialogCellEditor的control是一个Composite,而得到焦点的是这个Composite上的Button,当你在这上按Tab的时候,是Button收到事件监听而不是底下的Composite得到事件。因为要让DialogCellEditor也能有此功能,我们要多做一点点事情。

 

思路:还是事件模拟,我们要让button上的事件转到control上。

 

实现如下:写一个抽象的DialogCellEditor类,主要是为了实现事件的跳转:

 

public abstract class TraverseDialogCellEditor extends DialogCellEditor implements
		TraverseListener {

	public TraverseDialogCellEditor() {
		super();
	}

	public TraverseDialogCellEditor(Composite parent, int style) {
		super(parent, style);
	}

	public TraverseDialogCellEditor(Composite parent) {
		super(parent);
	}

	@Override
	protected Button createButton(Composite parent) {
		Button button = super.createButton(parent);
		button.addTraverseListener(this);
		return button;
	}

	public void keyTraversed(TraverseEvent e) {
		Event event = new Event();
		event.time = e.time;
		event.character = e.character;
		getControl().notifyListeners(SWT.Traverse, event);
	}

}

 

给button加上TraverseListener,所有它的事件再转到control上。

 

OK了。可以试试效果去了!

 

 

你可能感兴趣的:(Excel)