JTable с редактором JComboBox: можно ли редактировать значение ячейки с клавиатуры одним нажатием клавиши - PullRequest
4 голосов
/ 27 января 2010

У меня JTable, содержащий редакторы JComboBox, инициализированные примерно как

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, но если есть более простое решение, которое было бы неплохо =)

ш, Ток

Ответы [ 2 ]

2 голосов
/ 17 мая 2013

В случае, если кому-то все еще интересно, я делаю простую модификацию кода Тоуко, и это работает для меня:

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.Причина такого подхода заключается в том, что запрос фокуса не будет выполнен, если компонент редактора еще не виден.

Надеюсь, это может кому-нибудь помочь.

0 голосов
/ 27 июля 2011

Вы должны добавить KeyListener к своему коду.

Лучшее решение - добавить его в компонент JTable, где вы кладете JComboBox, и реализовать метод 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
        }
    }
});

Вы также можете комбинировать это решение со словарем, который связывает keyCode с интерфейсом действия.

Второму решению требуется следующий код: Глобальный атрибут (словарь):

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

Собственный интерфейс действий:

public interface MyAction {

    public void doAction();
}

И функция KeyListener.keyPressed () будет выглядеть следующим образом:

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
    }
}

Надеюсь, это поможет вам.

Привет!

...