使用JComboBox编辑器的JTable:是否可以通过一键按下来从键盘编辑单元格值

时间:2010-01-27 13:04:12

标签: swing jtable jcombobox tablecelleditor

我有一个包含JComboBox编辑器的JTable,有点像

JComboBox comboBox = ...;
TableColumn tc = table.getColumnModel().getColumn(i);
tc.setCellEditor(new DefaultCellEditor(comboBox));

这项工作正常,但我希望能够在表格中导航并仅使用键盘更新值。现在这可以使用组合框,但如果我想更新值“1”,我必须先按一个键激活组合框,然后按“1”选择项目。

所以,我想要的是我可以按“1”,只需按一次按键即可选择该项目。

对于文本单元格,我设法使用prepareEditor执行此操作,如下所示...

@Override
public Component prepareEditor(TableCellEditor editor, int row, int column) {
    Component c = super.prepareEditor(editor, row, column);
    if (c instanceof JTextComponent) {
        ((JTextComponent) c).selectAll();
    } 
    return c;
}

...但我还没弄清楚如何处理组合框。

一种可能性可能是自己的TableCellEditor,但是如果有一个更简单的解决方案会很好=)

BR, Touko

2 个答案:

答案 0 :(得分:2)

如果有人仍然感兴趣,我会对Touko的代码做一个简单的修改,这对我有用:

public class CustomTable extends JTable {
    private static final long serialVersionUID = -8855616864660280561L;

    public CustomTable(TableModel tableModel) {
        super(tableModel);
    }

    @Override
    public Component prepareEditor(TableCellEditor editor, int row, int column) {
        final Component comp =  super.prepareEditor(editor, row, column);

        // Text component should select all text when initiated for editing.
        if (comp instanceof JTextComponent)
            ((JTextComponent) comp).selectAll();

        // Try to obtain focus for the editor component.
        SwingUtilities.invokeLater(new Runnable() {
            @Override public void run() { comp.requestFocusInWindow(); }
        });

        return comp;
    }
}

所以基本上,我只是稍后使用SwingUtilities.invokeLater请求编辑器组件的焦点。这种方法的原因是,如果编辑器组件尚未可见,焦点请求将失败。

希望这可以帮助任何人。

答案 1 :(得分:0)

您必须在代码中添加KeyListener

最佳解决方案是将其添加到JTable放置JComboBox的{​​{1}}组件,并实施方法keyPressed(KeyEvent e)keyReleased(KeyEvent e)以了解哪个是JTable table = new JTable(); // Your necessary code (create combo box, cell editor...etc) table.addKeyListener(new KeyListener() { public void keyTyped(KeyEvent e) { } public void keyReleased(KeyEvent e) { } public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); switch(keyCode) { case KeyEvent.VK_1: // manage key 1 break; case KeyEvent.VK_A: // manage key A break; case KeyEvent.VK_F1: // manage key F1 break; case KeyEvent.VK_TAB: // manage key TAB break; default: // manage other keys } } }); 关键并采取必要的行动。

我在这里举个例子:

Map<Integer,MyAction> keyActions = new Hashmap<Integer,MyAction>();

您还可以将此解决方案与将keyCode与操作界面相关联的字典组合在一起。

此第二个解决方案需要以下代码: 全局属性(字典):

public interface MyAction {

    public void doAction();
}

自己的行动界面:

public void keyPressed(KeyEvent e) {
    int keyCode = e.getKeyCode();
    MyAction ma = keyActions.get(keyCode);
    if (ma != null) {
        ma.doAction();
    }
    else {
        // do default action for other keys
    }
}

KeyListener.keyPressed()函数如下:

{{1}}

我希望这会对你有所帮助。

问候!