0
votes

SWT Table has void setTopIndex(int index) and int getTopIndex().

I really need setTopPixel(int pixel) or setTopIndexFractional(double index).

I tried putting a Table into a ScrolledComposite, as such:

public class PixelTable extends ScrolledComposite {
    private final Table table;
    private final double itemHeight;

    public PixelTable(Composite parent) {
        super(parent, SWT.V_SCROLL | SWT.BORDER);

        // setup the ScrolledComposite
        table = new Table(this, SWT.VIRTUAL);
        this.setExpandHorizontal(true);
        this.setContent(table);
        itemHeight = table.getItemHeight();

        // setup the Table
        table.setLinesVisible(true);
        table.addListener(SWT.SetData, new Listener() {
            @Override
            public void handleEvent(Event e) {
                int row = e.index;
                TableItem item = (TableItem) e.item;
                item.setText(Integer.toString(row));
            }
        });
    }

    /** Returns the fractional top index. */
    public double getTopIndex() {
        return getOrigin().y / itemHeight;
    }

    /** Sets the fractional top index. */
    public void setTopIndex(double top) {
        this.setOrigin(0, (int) Math.round(top * itemHeight));
    }

    /** Sets the item count. */
    public void setItemCount(int count) {
        table.setItemCount(count);

        Point size = table.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        table.setSize(size);
    }
}

This works for while, but once the inner Table's size gets bigger than ~65,000 pixels (~2,500 rows), the Table shows its scroll bar as well (probably an unsigned short somewhere on the native side). Additionally, it will be pretty tricky to get Table headers to work with this approach, since they'll scroll away.

Does anybody know what the issues would be (or how to get started) to add a per-pixel interface to the SWT API? I'm willing to branch the SWT source if necessary. I only care about the latest APIs for Win / OS X / Linux (e.g. I don't care if I have to break compatibility with old stuff).

1

1 Answers

0
votes

If you want per-pixel scrolling, then just do the scrolling yourself. All you need to do is listen for SWT.MouseWheel, set Event#doit to false and then set the selection of the ScrollBar according to the scroll direction (increase/decrease by 1 (<-- that's the one pixel)).

Here is an example:

public static void main(String[] args)
{
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("StackOverflow");
    shell.setLayout(new FillLayout());

    final Table table = new Table(shell, SWT.V_SCROLL);

    for (int i = 0; i < 100; i++)
        new TableItem(table, SWT.NONE).setText("Item: " + i);

    table.addListener(SWT.MouseWheel, new Listener()
    {
        @Override
        public void handleEvent(Event e)
        {
            int increment = table.getVerticalBar().getSelection();
            if (e.count < 0)
                increment++;
            else if (e.count > 0)
                increment--;

            table.getVerticalBar().setSelection(increment);
            e.doit = false;
        }
    });

    shell.pack();
    shell.setSize(400, 200);
    shell.open();

    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
        {
            display.sleep();
        }
    }
    display.dispose();
}