[英]How to find index of SWT table column?
我有一個SWT表,它有零行和6列。
當我右鍵單擊任何一個表頭時,如何計算單擊的表列的索引?
我確實在某個時候右鍵單擊為TableHeader
Menu
編寫了一個CustomTable
。
此代碼可幫助您在右鍵單擊表頭時檢測TableColumn
。 但是,當列順序更改時,此代碼會中斷。 但您可以通過比較重新排序的列順序與原始列順序的索引來修復它。
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);
}
}
}
});
以下是一些可以滿足您需求的代碼:
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();
}
它基本上生成一個Map
將TableColumn
存儲為鍵,將位置存儲為值。
另外,您可以遍歷的所有列Table
的內Listener
,並比較它們單擊列。 第一種方法(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;
}
在表列定義中:
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偵聽器對右鍵單擊鼠標事件做出反應。 不是很直觀; name表明它主要用於規范上下文菜單外觀,但它也可以作為一般的右鍵單擊監聽器。 與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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.