SWT表:如何设置/获取“聚焦”行

时间:2012-01-13 15:06:00

标签: swt

在Windows和Linux上,按住 Ctrl 键时,可以使用插入符键上下移动而不更改选择。该表显示了一些视觉反馈。

我玩过一个使用TableCursor的SWT代码片段,但似乎已经半生不熟了,因为它引入了一些新错误 - 例如当按 Ctrl + 结束时,它会在释放 Ctrl 键后跳回到上一个选择。

如何获取或设置此“专注”行?

3 个答案:

答案 0 :(得分:2)

这看起来不像是可以直接获取/设置的属性,但是你可以从paint事件中检测出焦点行并自定义绘制焦点。

SWT.PaintItem事件的表格中添加Listener

handleEvent(PaintEvent e) {
    if (e.detail & SWT.FOSCUSED != 0)
        myFocusedRow = ((Table)e.widget).indexOf((TableItem)e.item);
    ...
    if (e.item == myFocusedItem)
        e.gc.drawFocus(e.x, e.y, e.width, e.height);
}

答案 1 :(得分:0)

我不确定这正是您所需要的,但如果您将Table包裹在TableViewer中,则可以使用TableViewerEditor作为细胞编辑支持。 (我相信您可以使用TableViewerEditor的焦点功能,而无需实际编辑任何单元格。)

这实际上覆盖了操作系统的焦点处理,但允许您以编程方式自定义焦点处理。我已经用它来启用键盘遍历进行单元格编辑。

这是一些快速而肮脏的示例代码,可以支持聚焦单元格。 (未经测试。例如,有可能启用单元格编辑支持 以使TableViewerEditor支持起作用。)

FocusCellHighlighter cellHighlighter = new FocusCellHighlighter(tableViewer);
TableViewerFocusCellManager focusManager = new TableViewerFocusCellManager(tableViewer, cellHighlighter);

TableViewerEditor.create(tableViewer, focusCellManager, new ColumnViewerActivationStrategy(tableViewer), TableViewerEditor.KEYBOARD_NAVIGATION);

然后您可以通过以下方式获得重点细胞:

ViewerCell focusedCell = viewer.getColumnViewerEditor().getFocusCell();
TableItem focusedItem = focusedCell != null ? focusedCell.getItem() : null;

请注意,这仅在Eclipse> = 3.3。

中启用

答案 2 :(得分:0)

要检测TableItem是否已聚焦,您可以将SWT.EraseItem或SWT.PaintItem类型的监听器添加到表中,并让它检查是否在事件的详细信息字段中设置了位标志SWT.FOCUSED。 (另见this Eclipse forum post。)

我找不到任何API来设置焦点项目,但有一个丑陋的工作:发布模拟项目点击的鼠标事件。这需要选择项目并在显示屏上显示。以下实用程序类包含执行此操作的方法:

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Widget;

/**
 * Utility class for tables.
 * 
 * @author Henno Vermeulen
 */
public final class Tables {

    private Tables() {
    }

    /**
     * Shows and selects the table <code>item</code> and lets it get the
     * keyboard focus.
     * 
     * <p>
     * Windows has a "focused" row (drawn with a dotted line) that can be moved
     * independently of the selected row (when pressing ctrl + up/down). This
     * method ensures that this focused row is made equal to the selected row so
     * that the selection does not jump to an unwanted location when the user
     * uses the up or down arrow on the keyboard.
     * 
     * <p>
     * Implementation detail: there is no API to get/set the focused row (see
     * also <a href="https://www.eclipse.org/forums/index.php/t/241852/">this
     * post</a> and <a href=
     * "http://stackoverflow.com/questions/8852574/swt-table-how-to-set-get-focused-row">
     * this one</a>), so we use a filthy hack: faking a mouse click in the
     * table.
     */
    public static void selectAndFocus(TableItem item) {
        fakeMouseClickTableItem(item);
    }

    private static void fakeMouseClickTableItem(TableItem item) {
        Table table = item.getParent();
        table.showItem(item);

        Point cursorLocation = item.getDisplay().getCursorLocation();
        fakeMouseClick(table, getCenter(item.getBounds(0)));
        item.getDisplay().setCursorLocation(cursorLocation);
    }

    private static Point getCenter(Rectangle bounds) {
        return new Point(bounds.x + bounds.width / 2,
                bounds.y + bounds.height / 2);
    }

    /**
     * Actually moves the mouse cursor to the given <code>location</code> so
     * that the OS gives the correct click behavior.
     */
    private static void fakeMouseClick(Control control, Point location) {
        control.getDisplay().setCursorLocation(control.toDisplay(location));
        control.getDisplay()
                .post(createMouseEvent(SWT.MouseDown, control, location));
        control.getDisplay()
                .post(createMouseEvent(SWT.MouseUp, control, location));
    }

    public static Event createMouseEvent(int type, Widget widget,
            Point position) {
        Event e = new Event();
        e.display = widget.getDisplay();
        e.widget = widget;
        e.type = type;
        e.x = position.x;
        e.y = position.y;
        e.count = 1;
        e.button = 1;
        e.doit = true;
        return e;
    }
}