Почему мой KeyListener не работает в Jpanel? [Дубликат]

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

Например:

class A;
class B1 : virtual A;
class B2 : virtual A;
class C: B1,B2 // A is shared, and would have one copy only.
75
задан Nathan 21 January 2016 в 22:59
поделиться

10 ответов

Вы должны добавить свой keyListener для каждого компонента, который вам нужен. Эти компоненты будут отправлять только компонент с фокусом. Например, если в вашем JFrame есть только один TextBox, то TextBox имеет фокус. Таким образом, вы должны добавить KeyListener и к этому компоненту.

Процесс тот же:

myComponent.addKeyListener(new KeyListener ...);

Примечание. Некоторые компоненты не могут быть сфокусированы, как JLabel.

Для настройки фокусировки вам необходимо:

myComponent.setFocusable(true);
46
ответ дан bruno conde 24 August 2018 в 07:24
поделиться

Если вы не хотите регистрировать слушателя на каждом компоненте, вы можете добавить свой собственный KeyEventDispatcher в KeyboardFocusManager:

public class MyFrame extends JFrame {    
    private class MyDispatcher implements KeyEventDispatcher {
        @Override
        public boolean dispatchKeyEvent(KeyEvent e) {
            if (e.getID() == KeyEvent.KEY_PRESSED) {
                System.out.println("tester");
            } else if (e.getID() == KeyEvent.KEY_RELEASED) {
                System.out.println("2test2");
            } else if (e.getID() == KeyEvent.KEY_TYPED) {
                System.out.println("3test3");
            }
            return false;
        }
    }
    public MyFrame() {
        add(new JTextField());
        System.out.println("test");
        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.addKeyEventDispatcher(new MyDispatcher());
    }

    public static void main(String[] args) {
        MyFrame f = new MyFrame();
        f.pack();
        f.setVisible(true);
    }
}
125
ответ дан Bjorn Tipling 24 August 2018 в 07:24
поделиться

lol .... все, что вам нужно сделать, это убедиться, что

addKeyListener (this);

правильно помещен в ваш код.

-2
ответ дан Chris 24 August 2018 в 07:24
поделиться

KeyListener является низким уровнем и применяется только к одному компоненту. Несмотря на попытки сделать его более удобным JFrame создает ряд компонентных компонентов, наиболее очевидным из которых является область содержимого. JComboBox Пользовательский интерфейс также часто реализуется аналогичным образом.

Стоит отметить, что события мыши работают странным образом, немного отличающимся от ключевых событий.

Подробнее о том, что вы должны do, см. мой ответ на Широкоэкранный ярлык приложения - Java Swing .

10
ответ дан Community 24 August 2018 в 07:24
поделиться

Хм .. для какого класса ваш конструктор? Возможно, какой-то класс расширяет JFrame? Конечно, фокус окна должен быть в окне, но я не думаю, что это проблема.

Я расширил ваш код, попытался запустить его, и он сработал - нажатие клавиш в результате печати. (запустить с помощью Ubuntu через Eclipse):

public class MyFrame extends JFrame {
    public MyFrame() {
        System.out.println("test");
        addKeyListener(new KeyListener() {
            public void keyPressed(KeyEvent e) {
                System.out.println("tester");
            }

            public void keyReleased(KeyEvent e) {
                System.out.println("2test2");
            }

            public void keyTyped(KeyEvent e) {
                System.out.println("3test3");
            }
        });
    }

    public static void main(String[] args) {
        MyFrame f = new MyFrame();
        f.pack();
        f.setVisible(true);
    }
}
8
ответ дан CSchulz 24 August 2018 в 07:24
поделиться

Пользовательские JComponents могут настраивать родительский JFrame.

Просто добавьте конструктор и перейдите в JFrame. Затем сделайте вызов setFocusable () в paintComponent.

Таким образом, JFrame всегда будет получать KeyEvents, независимо от того, нажаты ли другие компоненты.

-2
ответ дан Denizen 24 August 2018 в 07:24
поделиться

У меня такая же проблема, пока я не прочитал, что настоящая проблема связана с FOCUS, что ваш JFrame уже добавил Listeners, но кадр тура никогда не фокусируется на фокусе, потому что у вас есть много компонентов внутри вашего JFrame, которые также можно сфокусировать, поэтому попробуйте:

JFrame.setFocusable(true);

Удача

10
ответ дан Jérôme Verstrynge 24 August 2018 в 07:24
поделиться

InputMaps и ActionMaps были разработаны для захвата ключевых событий для компонента, его и всех его подкомпонентов или всего окна. Это контролируется с помощью параметра в JComponent.getInputMap (). См. Как использовать привязки клавиш для документации.

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

Этот код вызовет dispose () в JFrame, когда клавиша эвакуации будет удалена в любом месте окна. JFrame не является результатом JComponent, поэтому вам нужно использовать другой компонент в JFrame для создания привязки ключа. Область содержимого может быть таким компонентом.

InputMap inputMap; 
ActionMap actionMap;
AbstractAction action;
JComponent component;

inputMap  = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
actionMap = component.getActionMap();

action    = new AbstractAction()
{
   @Override
   public void actionPerformed(ActionEvent e)
   {
      dispose();
   }
};

inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dispose");
actionMap.put("dispose", action);
15
ответ дан Nathan 24 August 2018 в 07:24
поделиться

У меня такая же проблема. Я последовал за советом Бруно и обнаружил, что добавление KeyListener только к «первой» кнопке в JFrame (то есть в левом верхнем углу) сделало трюк. Но я согласен с вами, что это своего рода тревожное решение. Поэтому я пошарил и обнаружил более аккуратный способ исправить ситуацию. Просто добавьте строку

myChildOfJFrame.requestFocusInWindow();

к вашему основному методу после создания вашего экземпляра вашего подкласса JFrame и установите его видимым.

1
ответ дан pocketdora 24 August 2018 в 07:24
поделиться

Это должно помочь

    yourJFrame.setFocusable(true);
    yourJFrame.addKeyListener(new java.awt.event.KeyAdapter() {


        @Override
        public void keyTyped(KeyEvent e) {
            System.out.println("you typed a key");
        }

        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println("you pressed a key");
        }

        @Override
        public void keyReleased(KeyEvent e) {
            System.out.println("you released a key");
        }
    });
2
ответ дан Rahul 24 August 2018 в 07:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: