2013-06-25 112 views
4

我有一個SWT表,它有零行和6列。 當我右鍵單擊表頭中的任何一個,我如何計算 表右列的右鍵單擊索引? 請給一些片段。如何找到SWT表列的索引

在此先感謝 佳日

回答

3

下面是一些代碼,你想要做什麼:

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關鍵和值的位置。

或者,您可以遍歷Listener內的Table的所有列,並將它們與點擊列進行比較。第一種方法(Map)速度更快但使用更多的內存,而第二種方法(迭代)速度更慢但使用的內存更少。

+0

感謝很多不錯的片斷:)這是工作,而列選擇罰款,而列右鍵單擊。我試圖修改SWT.Selection SWT.MouseDown沒有運氣。任何輸入? – yash

+0

@yash有一個相當古老的bug報告[這裏](https://bugs.eclipse.org/bugs/show_bug.cgi?id=32322)表明'TableColumn'頭不支持右鍵單擊。 – Baz

+0

@yash但是,如果您使用的是右鍵單擊菜單,則可以查看[this](http://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/examples /org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet311.java)代碼示例並使用'SWT.MenuDetect'。 – Baz

1

上面的例子類似,但沒有使用地圖存儲指數:

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

請注意,這僅在列未移動時纔有效。只要列被移動,您就必須使用table.getColumnOrder()來確定列的索引。 – halfpad

4

我做了右鍵單擊一個CustomTableTableHeaderMenu寫回的某個時候。

此代碼可幫助您檢測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); 
       } 
      } 
     } 
    }); 
+0

如果表格控件的水平滾動條不在開始位置,此代碼是否可以工作? –

+0

@MikeNakis它應該,因爲headerHeight和clientArea計算w.r.t滾動條,如果存在。試一試。 – Niranjan

+0

我不認爲clientArea是計算w.r.t滾動條,在任何情況下,您的計算中都沒有使用clientArea.x來查找列,所以在我看來,即使clientArea受到滾動的影響,它也不起作用。既然你已經有了代碼,這大概是你寫的一些應用程序的一部分,你爲什麼不嘗試並告訴我們? –

0

在TableColumn的定義:

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

這裏是另一個拿。它明確地對右鍵單擊作出反應,適用於標題和普通行,空表和全表等,僅使用股票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; 
    } 
} 

screenshot from the example app showing also console output from it