我遇到了SWT Table
和JFace TableViewer
的问题。
我需要知道在哪一列上执行了右键单击。遗憾的是,TableColumn
和TableViewerColumn
无法识别右键单击事件。
所以我发现这个“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。如何获得滚动合成中第一个可见像素的位置?
希望你明白我的意思
修改:我需要在右键点击表格列标题时收到通知
答案 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();
}