Как обнаружить нажатие клавиши TAB в JComboBox? - PullRequest
3 голосов
/ 12 февраля 2012

Я пытаюсь выяснить, как определить, потерял ли фокус JComboBox при нажатии пользователем вкладки или щелчком мыши за пределами области компонента.

Добавление FocusListener в компонент редактора JComboBox мне не помогает, так как я не могу узнать, использовал ли пользователь мышь или переместил фокус с помощью клавиши табуляции. Любые идеи будут с благодарностью.

Редактировать 1: Я пытаюсь достичь этого:

  • Предположим, пользователь выпадает из списка (появляется JComboBox popupMenu) и перемещается с помощью клавиш курсора ...
  • Случай 1: пользователь нажимает вкладку. В этом случае я хочу отрезать часть информации от предмета и показывать только некоторые части.
  • Случай 2: пользователь щелкает мышью за пределами области popupMenu (здесь у нас есть подслучаи, но все они попадают в одну категорию). В этом случае я хочу изменить JComboBox, чтобы показать ранее отредактированный элемент, а не то, что пользователь прошел ...
  • Есть несколько других случаев (выбор элемента мыши, клавиша ввода, escape и т. Д.). Я мог бы легко справиться с этим, но обнаружить вкладку сложно, потому что я не могу поймать это событие, так как оно обрабатывается FocusManager.

Редактировать 2: Кажется, что я должен использовать setFocusTraversalKeysEnabled(false), чтобы получать уведомления при нажатии клавиши TAB, и когда я фиксирую это событие, я должен вручную перенести фокус ... Мне не нравится это решение, но это пока лучшее, что я мог прийти с.

Решение:

Следующий фрагмент кода Java фактически решает мою проблему. Как я писал в Edit 2 , самым простым решением было отключить обход фокуса. Я беззастенчиво позаимствовал код Клеопатры, и теперь все работает. :)

    if (!isTableCellEditor()) {
        comboBoxEditor.setFocusTraversalKeysEnabled(false);

        Action myAction = new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                handleTabPress();
                comboBoxEditor.transferFocus();
            } // actionPerformed() method
        };

        comboBoxEditor.getActionMap().put("tab-action", myAction);
        comboBoxEditor.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
            .put(KeyStroke.getKeyStroke("TAB"), "tab-action");
    } // if

Спасибо всем участникам обсуждения!

Ответы [ 2 ]

6 голосов
/ 12 февраля 2012

Насколько я понимаю ваш вопрос, есть две отдельные проблемы

  • не фиксируйте значение при навигации
  • принять реакцию на TAB

если да, то ответы

  • настроить комбо так, чтобы он считал, что это компонент редактирования CellEditorпользовательская привязка

В коде:

    final JComboBox simpleBox = new JComboBox(Locale.getAvailableLocales());
    // this line configures the combo to only commit on ENTER 
    // or selecting an item from the list
    simpleBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
    //
    // simpleBox.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
    //     Collections.EMPTY_SET);
    // just noticed the OPs edit - following indeed is easier to disable _all_ traversal
    // keys with one statement
    simpleBox.setFocusTraversalKeysEnabled(false);

    Action myAction = new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent e) {
            LOG.info("got it!");
            simpleBox.transferFocus();
        }

    };
    simpleBox.getActionMap().put("tab-action", myAction);
    simpleBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
       .put(KeyStroke.getKeyStroke("TAB"), "tab-action");
3 голосов
/ 12 февраля 2012

Предполагается, что вы нажали мышь (или клавишу) прямо перед тем, как потеряли фокус. Поэтому слушайте все щелчки клавиатуры и мыши, и виновником является тот, который использовался последним прямо перед потерей фокуса.

Когда срабатывает focuslost, вы можете проверить переменную, установленную при нажатии мыши или клавиши, в любой части вашего окна. Эта переменная просто регистрирует последнюю нажатую мышь и / или клавишу. Конечно, вам придется захватить все мыши и нажатия клавиш, так как нажатие на любой виджет позволит вам потерять фокус.

...