QA@IT

SWTテーブルのデータの編集

5305 PV

お世話になります。
org.eclipse.swt.custom.TableEditor を使った、テーブルデータの編集を調査しています。

それなりに動作するようになりました。タブを使ったセルの左右の移動は想定通りに動作します。
ただ、カーソルの上下でセルを移動しようとすると
org.eclipse.swt.widgets.Text#selectAll がうまく動作していないような振る舞いになります。
#keyTraversed の event.doit = false; が、効いていないように感じられます。

アドバイスいただけないでしょうか?

SWTは Windowsプラットフォームの 3.7.2 を利用しています。

ちょっと長いですが、確認コードを示します。
F2を押すか、マウスカーソルで突くと編集状態なります。
ESCやEnterで編集モードを抜けます。
Tab, Shift-Tab, カーソルの上下で編集中でも移動できる想定です。

import org.eclipse.swt.SWT;

class SwtCellEditor implements org.eclipse.swt.events.MouseListener
,org.eclipse.swt.events.KeyListener
,org.eclipse.swt.events.FocusListener
,org.eclipse.swt.events.TraverseListener {
    org.eclipse.swt.custom.TableCursor tc;
    org.eclipse.swt.custom.TableEditor te;

    static void createTableColAndContents(int rows, int cols, org.eclipse.swt.widgets.Table tbl){
        for (int i = 0; i < cols; i++){
            org.eclipse.swt.widgets.TableColumn col = 
                new org.eclipse.swt.widgets.TableColumn(tbl, SWT.LEFT);
            col.setText("Col" + i);
            col.setWidth(70);
        }
        for (int i = 0; i< rows; i++){
            String [] contents = {"Item0-" + i, "Item1-" + i, "Item2-" + i, "Item3-" + i};
            new org.eclipse.swt.widgets.TableItem(tbl, SWT.NONE).setText(contents);
        }
    }

    public static void main(String [] args) {
        org.eclipse.swt.widgets.Display display = 
                new org.eclipse.swt.widgets.Display();
        org.eclipse.swt.widgets.Shell shell = 
                new org.eclipse.swt.widgets.Shell(display);
        shell.setLayout(new org.eclipse.swt.layout.FillLayout());

        org.eclipse.swt.widgets.Table tbl;
        tbl = new org.eclipse.swt.widgets.Table(shell, SWT.SINGLE | SWT.BORDER | SWT.HIDE_SELECTION);
        tbl.setHeaderVisible(true);
        tbl.setLinesVisible(true);
        createTableColAndContents(10, 6, tbl);
        new SwtCellEditor(tbl, true);

        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }
        display.dispose();
    }

    SwtCellEditor(org.eclipse.swt.widgets.Table tbl, boolean withCursor) {
        if (withCursor) {
            tc = new org.eclipse.swt.custom.TableCursor(tbl, 0);
            tc.addMouseListener(this);
            tc.addKeyListener(this);
            tc.setSelection(0, 0);
        }

        te = new org.eclipse.swt.custom.TableEditor(tbl);
        org.eclipse.swt.widgets.Text text = new org.eclipse.swt.widgets.Text(tbl, 0);
        te.horizontalAlignment = SWT.LEFT;
        te.grabHorizontal = te.grabVertical = true;
        tbl.addMouseListener(this);
        tbl.addKeyListener(this);
        text.addTraverseListener(this);
        text.addFocusListener(this);
        text.addKeyListener(this);
        te.setEditor(text);
    }

    public void focusGained(org.eclipse.swt.events.FocusEvent event) { }

    public void focusLost(org.eclipse.swt.events.FocusEvent event) {
        org.eclipse.swt.widgets.Text text = (org.eclipse.swt.widgets.Text)event.getSource();
        org.eclipse.swt.widgets.Table tbl = (org.eclipse.swt.widgets.Table)text.getParent();
        org.eclipse.swt.widgets.TableItem item = te.getItem();
        item.setText(te.getColumn(), text.getText());
        text.setVisible(false);
        if (tc != null) {
            tc.setVisible(true);
            tc.setSelection(tbl.indexOf(item), te.getColumn());
        }
        else {
            tbl.setSelection(tbl.indexOf(item));
        }
    }

    public void keyPressed(org.eclipse.swt.events.KeyEvent event) {
        Object src = event.getSource();
        if (src instanceof org.eclipse.swt.widgets.Text) {
            switch(event.keyCode) {
            case SWT.KeyUp:    case SWT.KeyDown:
                event.doit = false;
            }
            return;
        }

        if (src instanceof org.eclipse.swt.custom.TableCursor) {
            switch(event.keyCode) {
            case SWT.F2:
                org.eclipse.swt.widgets.TableItem item = tc.getRow();
                org.eclipse.swt.widgets.Text text = (org.eclipse.swt.widgets.Text)te.getEditor();
                int col = tc.getColumn();
                if (col < 0) col = te.getColumn();
                text.setText(item.getText(col));
                text.selectAll();
                te.setEditor(text, item, col);
                text.setFocus();
                tc.setVisible(false);
                event.doit = false;
            }
            return;
        }

        org.eclipse.swt.widgets.Table tbl = (org.eclipse.swt.widgets.Table)src;
        switch(event.keyCode) {
        case SWT.F2:
            int row = tbl.getSelectionIndex();
            if (row < 0) return;
            org.eclipse.swt.widgets.TableItem item = tbl.getItem(row);
            org.eclipse.swt.widgets.Text text = (org.eclipse.swt.widgets.Text)te.getEditor();
            int col = te.getColumn();
            if (col < 0) col = 0;
            text.setText(item.getText(col));
            text.selectAll();
            te.setEditor(text, item, col);
            text.setFocus();
            event.doit = false;
        }
    }

    public void keyReleased(org.eclipse.swt.events.KeyEvent event) { }

    public void keyTraversed(org.eclipse.swt.events.TraverseEvent event) {
        org.eclipse.swt.widgets.Text text = (org.eclipse.swt.widgets.Text)event.getSource();
        org.eclipse.swt.widgets.Table tbl = (org.eclipse.swt.widgets.Table)text.getParent();
        org.eclipse.swt.widgets.TableItem item = te.getItem();
        int col = te.getColumn(), row = tbl.indexOf(item);

        switch (event.detail) {
        case SWT.TRAVERSE_TAB_NEXT:
            int cc = tbl.getColumnCount();
            item.setText(col, text.getText());
            col = col < cc - 1 ? col + 1 : 0; 
            text.setText(item.getText(col));
            text.selectAll();
            te.setEditor(text, item, col);
            event.doit = false;
            break;

        case SWT.TRAVERSE_TAB_PREVIOUS:
            cc = tbl.getColumnCount();
            item.setText(col, text.getText());
            col = col > 0 ? col - 1 : cc - 1; 
            text.setText(item.getText(col));
            text.selectAll();
            te.setEditor(text, item, col);
            event.doit = false;
            break;

        case SWT.TRAVERSE_ARROW_NEXT:
            if (event.keyCode == SWT.ARROW_RIGHT) break;
            int rc = tbl.getItemCount();
            item.setText(col, text.getText());
            row = row < rc - 1 ? row + 1 : 0; 
            item = tbl.getItem(row);
            text.setText(item.getText(col));
            text.selectAll();
            te.setEditor(text, item, col);
            event.doit = false;
            break;

        case SWT.TRAVERSE_ARROW_PREVIOUS:
            if (event.keyCode == SWT.ARROW_LEFT) break;
            rc = tbl.getItemCount();
            item.setText(col, text.getText());
            row = row > 0 ? row - 1 : rc - 1;
            item = tbl.getItem(row);
            te.setEditor(text, item, col);
            text.setText(item.getText(col));
            text.selectAll();
            event.doit = false;
            break;

        case SWT.TRAVERSE_RETURN:
            item.setText(col, text.getText()); 
            text.setVisible(false);
            break;
        case SWT.TRAVERSE_ESCAPE:
            text.setVisible(false);
            event.doit = false;
            break;
        }
    }

    public void mouseDown(org.eclipse.swt.events.MouseEvent event) {
        int col = -1;
        org.eclipse.swt.widgets.TableItem item;

        Object src = event.getSource();
        if (src instanceof org.eclipse.swt.custom.TableCursor) {
            item = tc.getRow();
            col = tc.getColumn();
            tc.setVisible(false);
        }
        else {
            org.eclipse.swt.widgets.Table tbl = (org.eclipse.swt.widgets.Table)src;
            int row = tbl.getSelectionIndex();
            if (row < 0) return;
            item = tbl.getItem(row);
            org.eclipse.swt.graphics.Point pt = new org.eclipse.swt.graphics.Point(event.x, event.y);
            for (int i = 0, n = tbl.getColumnCount(); i < n; i++) {
                if (item.getBounds(i).contains(pt)) { col = i; break; }
            }
            if (col < 0) return;
        }

        org.eclipse.swt.widgets.Text text = (org.eclipse.swt.widgets.Text)te.getEditor();
        text.setText(item.getText(col));
        text.selectAll();
        te.setEditor(text, item, col);
        text.setFocus();
    }

    public void mouseUp(org.eclipse.swt.events.MouseEvent e) { }
    public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) {    }
}
ウォッチ

この質問への回答やコメントをメールでお知らせします。