How to find SWT table column index

I have a SWT table that has zero rows and 6 columns. When I right-click on any table header, how can I calculate the index of a column of a table that is right-clicked? Please give some fragments.

Thanks in advance yash

+4
source share
5 answers

Here is the code that does what you want:

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(); } 

It basically generates a Map , storing the TableColumn as key and position as a value.

Alternatively, you can iterate over all Table columns within the Listener and compare them with the column with a click. The first approach (Map) is faster, but uses more memory, while the second approach (iteration) is slower, but uses less memmory.

+3
source

I wrote CustomTable for the TableHeader Menu on the right side of the mouse.

This code helps you locate a TableColumn when you right-click on a table header. But this code is interrupted when the column order changes. But you can fix this by comparing the indexes of the ordered order of columns of order vs.

 addListener(SWT.MenuDetect, new Listener() { @Override public void handleEvent(Event e) { Point pt = getShell().getDisplay().map(null, CustomTable.this, new Point(ex, ey)); 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(ex, ey); headerMenu.setVisible(true); e.doit = false; } else { headerMenu.setVisible(false); CustomTable.super.setMenu(tableMenu); if(tableMenu != null){ tableMenu.setLocation(ex, ey); tableMenu.setVisible(true); } } } }); 
+4
source

As in the previous example, but without using a map to store indexes:

 ... 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; } 
+1
source

in the table definitions:

 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++; 

and etc.

in the handler:

 int index = (int) ((TableColumn) e.widget).getData(); 
0
source

here is another take. He finally reacts to the right click, works both in headers and in regular rows, empty tables and full tables, using only the SWT table for stocks.

This approach uses a combination of a SWT.MenuDetect listener and a "fake TableItem" created and placed only to identify the column at that position. I did not notice any unwanted visual side effects such as flicker or flash. This is likely due to the fact that the fake item is located inside the event processing before the rest of the user interface can notice its existence.

The SWT.MenuDetect listener responds to a mouse event with the right mouse button. Not very intuitive; the name suggests that it was intended primarily to regulate the appearance of the context menu, but it does its job just like a regular right-click listener. It is also emitted by the table header, unlike SWT.MouseDown. Good! Unfortunately, unlike SWT.Selection, e.widget refers to the whole table, not just columns or cells, therefore it is useless for our purposes, as it is used in the Baz answer. The column must be detected using a low-level approach with physical coordinates.

Here is the code:

 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(ex, ey); 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; } } 

screenshot from an example application also showing console output from it

0
source

Source: https://habr.com/ru/post/1487998/


All Articles