在ScrolledForm SWT中获取x坐标

时间:2014-03-05 09:46:00

标签: java swt eclipse-rcp pixel jface

我遇到了SWT Table和JFace TableViewer的问题。 我需要知道在哪一列上执行了右键单击。遗憾的是,TableColumnTableViewerColumn无法识别右键单击事件。

所以我发现这个“hack”来检查在屏幕上执行鼠标点击的位置,获取y坐标并添加每个表列的宽度,只要该值小于y坐标。

如果y坐标位于添加的宽度之间,则添加的最后一列是右键单击的。见下文。

    int width = 0; // the start point. 0 only works if not scrolled

    final TableColumn[] sorted = new TableColumn[table.getColumns().length];
    final int[] order = table.getColumnOrder();
    int ctn = 0;
    for( final int i : order )
    {
      sorted[ctn] = table.getColumn( i );
      ctn++;
    }

    for( int i = 0; i < table.getColumns().length; i++ )
    {
      final TableColumn tc = sorted[i];


      if( (width < point.x) && (point.x < (width + tc.getWidth())) )
      {

       rightClickedColumn = tc; // the colums is in the range, so this is the one clicked on

      }
      width += tc.getWidth(); // add the width of this columns so we can check the next one
    }

只要不滚动保存TableViewer的合成,这样就可以正常工作。

当滚动时,起始值0不再正确,它必须是原始0和从表中可见的第一个像素之间的差异。 因此,如果表格的100px不可见,我想得到这100px。如何获得滚动合成中第一个可见像素的位置?

希望你明白我的意思

修改:我需要在右键点击表格列标题时收到通知

1 个答案:

答案 0 :(得分:2)

您应该使用TableColumn#getWidth()来确定您所在的列,而不是使用TableItem#getBounds()

以下是一个例子:

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

    ScrolledComposite comp = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
    comp.setLayout(new FillLayout());

    final Table table = new Table(comp, SWT.BORDER | SWT.FULL_SELECTION);
    table.setHeaderVisible(true);
    table.setLinesVisible(true);
    for (int i = 0; i < 4; i++)
    {
        TableColumn column = new TableColumn(table, SWT.NONE);
        column.setText("Column " + i);
    }
    for (int i = 0; i < 64; i++)
    {
        TableItem item = new TableItem(table, SWT.NONE);
        for (int j = 0; j < table.getColumnCount(); j++)
        {
            item.setText(j, "Item " + i + "-" + j);
        }
    }
    for (int i = 0; i < table.getColumnCount(); i++)
    {
        table.getColumn(i).pack();
    }
    table.addListener(SWT.MouseDown, new Listener()
    {
        public void handleEvent(Event event)
        {
            Point pt = new Point(event.x, event.y);
            TableItem item = table.getItem(pt);
            if (item == null)
                return;
            for (int i = 0; i < table.getColumnCount(); i++)
            {
                Rectangle rect = item.getBounds(i);
                if (rect.contains(pt))
                {
                    int index = table.indexOf(item);
                    System.out.println("Item " + index + "-" + i);
                }
            }
        }
    });

    comp.setContent(table);
    comp.setExpandHorizontal(true);
    comp.setExpandVertical(true);
    comp.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));

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

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

它将显示所选的表格单元格(行和列)。


<强>更新

如果您想在表格标题上侦听点击事件,请将第一个for循环替换为:

for (int i = 0; i < 4; i++)
{
    final TableColumn column = new TableColumn(table, SWT.NONE);
    column.setText("Column " + i);
    column.addListener(SWT.Selection, new Listener()
    {
        @Override
        public void handleEvent(Event arg0)
        {
            System.out.println(column.getText());
        }
    });
}

更新2

检测右键单击Table标题有点棘手。错误报告here表示SWT.MenuDetect无法使用TableColumn

但是,有一种解决方法:

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

    ScrolledComposite comp = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
    comp.setLayout(new FillLayout());

    final Table table = new Table(comp, SWT.BORDER | SWT.FULL_SELECTION);
    table.setHeaderVisible(true);
    table.setLinesVisible(true);
    for (int i = 0; i < 4; i++)
    {
        final TableColumn column = new TableColumn(table, SWT.NONE);
        column.setText("Column " + i);
    }
    for (int i = 0; i < 64; i++)
    {
        TableItem item = new TableItem(table, SWT.NONE);
        for (int j = 0; j < table.getColumnCount(); j++)
        {
            item.setText(j, "Item " + i + "-" + j);
        }
    }
    for (int i = 0; i < table.getColumnCount(); i++)
    {
        table.getColumn(i).pack();
    }

    table.addListener(SWT.MenuDetect, new Listener()
    {
        @Override
        public void handleEvent(Event event)
        {
            Point pt = display.map(null, table, new Point(event.x, event.y));
            Rectangle clientArea = table.getClientArea();
            boolean header = clientArea.y <= pt.y && pt.y < (clientArea.y + table.getHeaderHeight());

            if (header)
            {
                TableItem item = table.getItem(0);
                for (int i = 0; i < table.getColumnCount(); i++)
                {
                    Rectangle rect = item.getBounds(i);
                    if (pt.x >= rect.x && pt.x <= rect.x + rect.width)
                    {
                        System.out.println("Header " + i);
                    }
                }
            }
        }
    });

    comp.setContent(table);
    comp.setExpandHorizontal(true);
    comp.setExpandVertical(true);
    comp.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));

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

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