Получение фокуса на JPanel

У меня есть JPanel внутри JFrame. Я зарегистрировал KeyListener, на основе которого хочу обновить JPanel. У меня проблема в том, что я не могу сфокусироваться на JPanel, и поэтому мой KeyListener не работает. Я уже знаю, что KeyListener работает, потому что я зарегистрировал его с JFrame, и он работал нормально. Мой код на данный момент выглядит примерно так:

myFrame.setFocusable(false);
myPanel.setFocusable(true);
myPanel.addKeyListener(myKL);
myFrame.add(myPanel);

Кто-нибудь сталкивался с такой проблемой раньше? Есть ли что-то, что я упускаю в связи с этим?

P.S.: У меня нет никаких компонентов внутри JPanel. Я просто рисую изображение на фоне, поэтому мне нужно, чтобы фокус был на самой JPanel, а не на чем-то внутри нее.


person Vlad T.    schedule 25.01.2010    source источник
comment
Хм, с добавлением myPanel.requestFocus() это работает для меня. Какую версию Java вы используете?   -  person Joshua McKinnon    schedule 25.01.2010
comment
Возможно, опубликуйте SSCCE (простой автономный компилируемый пример), который воспроизводит это. Это даст другим возможность работать, чтобы помочь. Я также замечаю проблему, сужая ее до наименьшего масштаба, иногда я могу найти решение самостоятельно.   -  person broschb    schedule 26.01.2010


Ответы (5)


Хотя вы указываете, что панель может быть сфокусирована, панель не запрашивает фокус. Попробуйте использовать myPanel.requestFocus();.

person David Koelle    schedule 25.01.2010
comment
Спасибо за Ваш ответ. Пробовал как requestFocus(), так и requestFocusInWindow(), ни один из них не позволяет панели получить фокус. Есть ли у вас другие предложения? - person Vlad T.; 25.01.2010
comment
Это может зависеть от того, когда вы его вызываете. Не вызывайте его, например, в конструкторе JPanel, поскольку он вызывается до отображения панели. - person David Koelle; 26.01.2010
comment
Спасибо, Дэвид, этот ответ сработал для меня, я понятия не имел, что не могу позвонить из конструктора. Как только я переместил requestFocus() в метод, который вызывался после отображения на экране, он работал отлично. - person Vlad T.; 26.01.2010

Используйте setFocusable(true), а затем requestFocusInWindow(). Но последнее должно быть выполнено после того, как окно, содержащее панель, станет видимым, для чего вам, вероятно, потребуется зарегистрировать прослушиватель окна и выполнить requestFocusInWindow() в обработчике активации окна. код.

Примечание. В частности, после того, как окно отображается, а не только после вызова setVisible(true).

person Lawrence Dol    schedule 26.01.2010
comment
Итак, как мой код может сказать, когда окно является видимым, если ожидание после вызова setVisible(true) недостаточно? - person Gavin S. Yancey; 10.07.2019
comment
Для меня это сработало, когда я позвонил panel.requestFocusInWindow() после frame.pack(). - person ZeroFunter; 08.02.2020
comment
Как правило, объединение команд Swing в SwingUtilities.invokeLater(()->{...});, даже если вы уже находитесь в потоке Swing, может решить такие проблемы, потому что (говорят в документации) это произойдет после обработки всех ожидающих событий AWT. Например: если вы хотите защитить код события Swing от его собственного выполнения, вы можете установить логическое значение в начале, а в конце сбросить логическое значение, но последнее должно быть в invokeLater(), иначе сброс находится слишком рано в последовательности событий. - person Dreamspace President; 28.09.2020

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

person Uri    schedule 25.01.2010

Пытаться

panel.setFocusable(true);
panel.setRequestFocusEnabled(true);

// some code here

panel.grabFocus();
person John Doe    schedule 25.01.2010

Попробуйте что-то вроде этого:

    myFrame.addFocusListener(new FocusAdapter() {

        /**
         * {@inheritDoc}
         */
        @Override
        public void focusGained(FocusEvent aE) {
            myPanel.requestFocusInWindow();
        }
    });
person Bram Janssens    schedule 04.09.2014