How to do a discrete (row-by-row) scrolling in SWT Table
(JFace TableViewer
)?
I need a Table
to be scrolled "one unbroken row at a time", putting a full cell on top.
I use JFace TableViewer
, but I didn't find a way to add a mouse-listener to it, so I made something like this:
TableViewer table = new TableViewer(shell, SWT.BORDER_DASH |SWT.FULL_SELECTION);
//some visual settings ommited here
table.getControl().addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseScrolled(MouseEvent e) {
Table sourceControl = (Table)e.getSource();
System.out.println(e.count);
if(e.count >=0)
sourceControl.setTopIndex(sourceControl.getTopIndex()-1);
else
sourceControl.setTopIndex(sourceControl.getTopIndex()+1);
}
});
But it turned out, that first of all if e.count
equals to 3 or more, some rows are being missed. Secondly sometimes setTopIndex()
not placing rows correctly.
Can it be done in more accurate way?
From what I can tell, adding a e.doit = false
in the Listener
works perfectly. Here is an example:
public static void main(String[] args)
{
final Display display = new Display();
Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new FillLayout());
final Table table = new Table(shell, SWT.NONE);
for (int i = 0; i < 100; i++)
{
TableItem item = new TableItem(table, SWT.NONE);
item.setText("Item " + i);
}
table.addListener(SWT.MouseWheel, new Listener()
{
@Override
public void handleEvent(Event e)
{
e.doit = false;
if (e.count >= 0)
table.setTopIndex(table.getTopIndex() - 1);
else
table.setTopIndex(table.getTopIndex() + 1);
}
});
shell.pack();
shell.setSize(shell.getSize().x, 300);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
The only case where the TableItem
at the top isn't displayed completely is when you reach the end of the Table
and the table's height isn't an exact multiple of the TableItem
's height.