Java 如何查找SWT表列的索引?
我有一个SWT表,它有零行和6列Java 如何查找SWT表列的索引?,java,swt,Java,Swt,我有一个SWT表,它有零行和6列 当我右键单击任何一个表标题时,如何计算所单击的表列的索引?以下是一些代码,可以满足您的需要: private static Map<TableColumn, Integer> mapping = new HashMap<TableColumn, Integer>(); public static void main(String[] args) { Display display = new Display(); fin
当我右键单击任何一个表标题时,如何计算所单击的表列的索引?以下是一些代码,可以满足您的需要:
private static Map<TableColumn, Integer> mapping = new HashMap<TableColumn, Integer>();
public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new FillLayout());
Listener listener = new Listener()
{
@Override
public void handleEvent(Event arg0)
{
TableColumn column = (TableColumn) arg0.widget;
System.out.println(mapping.get(column));
}
};
Table table = new Table(shell, SWT.NONE);
table.setHeaderVisible(true);
for(int i = 0; i < 5; i++)
{
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText("Column " + i);
column.addListener(SWT.Selection, listener);
column.pack();
mapping.put(column, i);
}
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private静态映射=newhashmap();
公共静态void main(字符串[]args)
{
显示=新显示();
最终外壳=新外壳(显示);
shell.setText(“StackOverflow”);
setLayout(新的FillLayout());
侦听器侦听器=新侦听器()
{
@凌驾
公共无效handleEvent(事件arg0)
{
TableColumn=(TableColumn)arg0.widget;
System.out.println(mapping.get(column));
}
};
表=新表(壳牌,SWT.NONE);
表.setheadervible(true);
对于(int i=0;i<5;i++)
{
TableColumn column=新的TableColumn(表,SWT.NONE);
列.setText(“列”+i);
column.addListener(SWT.Selection,listener);
column.pack();
mapping.put(第i列);
}
shell.pack();
shell.open();
而(!shell.isDisposed())
{
如果(!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
它基本上生成一个映射
,将表格列
存储为键,位置存储为值
或者,您可以迭代
侦听器中表的所有列
,并将它们与单击的列进行比较。第一种方法(Map)速度更快,但使用更多内存,而第二种方法(迭代)速度较慢,但使用更少内存。与上述示例类似,但不使用Map存储索引:
...
column.addSelectionListener(getSelectionAdapter1(tbl.getColumnCount()-1));
...
private SelectionAdapter getSelectionAdapter1(final int index) {
SelectionAdapter selectionAdapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
System.out.println(index);
}
};
return selectionAdapter;
}
在右键单击返回时,我确实为TableHeader
菜单编写了CustomTable
此代码帮助您在右键单击表格标题时检测表格列
。但是,当列顺序更改时,此代码将中断。但是您可以通过比较重新排序的列顺序与原始列顺序的索引来修复它
addListener(SWT.MenuDetect, new Listener() {
@Override
public void handleEvent(Event e) {
Point pt = getShell().getDisplay().map(null, CustomTable.this, new Point(e.x, e.y));
Rectangle clientArea = CustomTable.this.getClientArea();
boolean header = clientArea.y <= pt.y && pt.y < (clientArea.y + CustomTable.this.getHeaderHeight());
//code to calculate column of Right click - START
int width = 0;
for(int i = 0; i< CustomTable.this.getColumns().length; i++){
TableColumn tc = CustomTable.this.getColumns()[i];
if(width < pt.x && pt.x < width + tc.getWidth()){
System.out.println("Right Click on " + tc.getText());
}
width += tc.getWidth();
}
//code to calculate column of Right click - END
if (header) {
if(tableMenu != null){
tableMenu.setVisible(false);
}
CustomTable.super.setMenu(headerMenu);
headerMenu.setLocation(e.x, e.y);
headerMenu.setVisible(true);
e.doit = false;
} else {
headerMenu.setVisible(false);
CustomTable.super.setMenu(tableMenu);
if(tableMenu != null){
tableMenu.setLocation(e.x, e.y);
tableMenu.setVisible(true);
}
}
}
});
addListener(SWT.MenuDetect,newlistener()){
@凌驾
公共无效handleEvent(事件e){
点pt=getShell().getDisplay().map(null,CustomTable.this,新点(e.x,e.y));
矩形clientArea=CustomTable.this.getClientArea();
布尔标题=表格列定义中的clientArea.y:
int index = 0;
TableColumn column1 = new TableColumn(table, SWT.NONE);
column1.setText("Column 1 header");
column1.setData(index);
index++;
TableColumn column2 = new TableColumn(table, SWT.NONE);
column2.setText("Column 2 header");
column2.setData(index);
index++;
等等
在处理程序中:
int index = (int) ((TableColumn) e.widget).getData();
这是另一个例子。它在右键单击时会做出明确的反应,适用于标题和普通行,空表和满表,只使用一个库存SWT表
此方法使用SWT.MenuDetect侦听器和“假TableItem”的组合,创建和处理只是为了在给定位置识别列。我没有注意到任何不希望出现的视觉副作用,如闪烁或闪光外观。这可能是由于在UI的其他部分注意到它的存在之前,在事件处理内部处理了假项
SWT.MenuDetect侦听器会对鼠标右键单击事件做出反应。这不是很直观;名称表明它主要用于调节上下文菜单的外观,但它也可以作为普通的鼠标右键单击侦听器来完成其工作。
与SWT.MouseDown不同,它也是由表头发出的。很好!
不幸的是,与SWT.Selection不同,e.widget引用的是整个表,而不仅仅是列或单元格,因此对于我们的目的来说是无用的,因为它用于Baz响应。必须使用物理坐标的低级方法来检测列
代码如下:
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
/**
* Table with right click detection that works for table headers and empty
* tables. It was tested as working for columns reordering, moving or resizing.
*
* @author Espinosa
*/
public class TableWithRightClickDetection {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Table with right click detection");
shell.setLayout(new FillLayout());
shell.setSize(400, 300);
final Table table = new Table(shell, SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION);
table.setHeaderVisible(true);
table.setLinesVisible(true);
int columnCount = 4;
for (int i = 0; i < columnCount; i++) {
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText("Column " + i);
column.setMoveable(true);
column.setResizable(true);
table.getColumn(i).pack();
}
table.addListener(SWT.MenuDetect, (e) -> {
// SWT.MenuDetect reacts on right-click
// It is emitted by table header, unlike SWT.MouseDown.
// Also unlike SWT.Selection the e.widget references whole
// Table, not just column or cell, unfortunately, so this has
// to be detected using low level approach with physical coordinates.
Point ptAbsolute = new Point(e.x, e.y);
Point pt = table.toControl(ptAbsolute); // get position relative to the Tree widget
int colIndex = columnAtPoint(table, pt);
if (colIndex >= 0) {
if (pt.y < table.getHeaderHeight()) {
// for Tree/TreeViews negative Y means table header
System.out.println("Header right-clicked on column " + colIndex);
} else {
System.out.println("Row right-clicked on column " + colIndex);
}
}
// prevent showing context menu (if there is any declared)
e.doit = false;
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
/**
* @return column index for given coordinates relative to the given Table widget
*/
private static int columnAtPoint(Table table, Point pt) {
int colIndex = -1;
// The only way how to get column bounds is to get TableItem
// But empty table hasn't got any and headers does not count.
// The only way is to temporarily create one and then immediately dispose.
TableItem fakeRow = new TableItem(table, 0);
for (int i = 0; i < table.getColumnCount(); i++) {
Rectangle rec = fakeRow.getBounds(i);
// It is safer to use X coordinate comparison directly rather then
// rec.contains(pt)
// This way also works for Tree/TreeViews.
if ((pt.x > rec.x) && (pt.x < (rec.x + rec.width))) {
colIndex = i;
}
}
fakeRow.dispose();
// Not the most efficient way. Rectangles obtained from "fake row" can be cached
// and recomputed on column resizes, moves and swaps.
return colIndex;
}
}
import org.eclipse.swt.swt;
导入org.eclipse.swt.graphics.Point;
导入org.eclipse.swt.graphics.Rectangle;
导入org.eclipse.swt.layout.FillLayout;
导入org.eclipse.swt.widgets.Display;
导入org.eclipse.swt.widgets.Shell;
导入org.eclipse.swt.widgets.Table;
导入org.eclipse.swt.widgets.TableColumn;
导入org.eclipse.swt.widgets.TableItem;
/**
*具有右键单击检测的表,适用于表标题和空
*它被测试为对列进行重新排序、移动或调整大小。
*
*@作者埃斯皮诺萨
*/
具有RightClickDetection的公共类表{
公共静态void main(字符串[]args){
显示=新显示();
外壳=新外壳(显示);
setText(“具有右键单击检测的表”);
setLayout(新的FillLayout());
外壳尺寸(400300);
最终表格=新表格(shell,SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION);
表.setheadervible(true);
表.setLinesVisible(真);
int columnCount=4;
对于(int i=0;i{
//SWT.MenuDetect在右键单击时作出反应
//它由表头发出,与SWT.MouseDown不同。
//与SWT.Selection不同,e.widget引用了整个
//表,而不仅仅是列或单元格,不幸的是,因此
//使用物理坐标的低电平方法进行检测。
点P绝对=新点(e.x,e.y);
Point pt=table.toControl(ptAbsolute);//获取相对于树小部件的位置
int colIndex=列点(表,pt);
如果(colIndex>=0){
if(pt.y