Как найти JComponent, который имеет фокус в приложении Swing?

У меня возникают проблемы с определением, куда переходит фокус в моем приложении после активации/деактивации или открытия/закрытия некоторых диалогов.

Есть ли способ безопасно передать событие вниз по иерархии компонентов, чтобы получать информацию, когда фокус меняется и куда?

Например, в среде Smalltalk вы можете по причинам тестирования просто повторно реализовать #requestFocus на уровне Window/SubPane (т. е. JComponent) и иметь оператор отладки, куда переместился фокус.

Можете ли вы сделать что-то подобное на Java или есть какой-то механизм, который мне не хватает?

Фокус возвращается к компоненту, который последним был в фокусе перед отображением другого окна. Не уверен, почему вы думаете, что вам нужно знать, какой компонент имеет фокус. Какую проблему вы пытаетесь решить? Может быть, вы можете использовать WindowListner, чтобы знать, когда окно активировано. Тогда, возможно, используйте KeyBoardFocusManager.

camickr 20.03.2022 14:36

Итак, у меня есть InputMap/ActionMap, определенный для компонента. Это работает идеально большую часть времени. Однако у меня бывают ситуации, когда, например, событие клавиши ESC перехватывается где-то, что означает, что мне нужно несколько раз нажать ESC, чтобы приложение закрылось, и я действительно хотел бы знать, почему. У меня есть навязчивое подозрение, что Фокус уходит от Компонента, и я хотел бы в этом убедиться. Кроме того, я хотел бы узнать больше о том, как это работает в Swing. Спасибо, что указали на KeyBoardFocusManager, это уже выглядит действительно полезным.

Snorik 20.03.2022 18:01
Мне нужно нажать ESC несколько раз, чтобы закрыть приложение Похоже, вы пытаетесь закрыть фрейм/диалог с помощью клавиши выхода. Да, иногда нужно дважды нажать escape. Например, если раскрывающийся список со списком виден, первый выход закроет всплывающее окно, а второй — диалоговое окно. Проверьте Клавиша Escape и диалоговое окно, чтобы увидеть, работает ли он лучше.
camickr 20.03.2022 22:28

@camickr спасибо - я дам обновление. Но все же хотелось бы понять, чем закончились события.

Snorik 21.03.2022 11:27

Swing использует привязки клавиш для всех своих компонентов. Таким образом, любой компонент, использующий привязку WHEN_IN_FOCUS, будет иметь приоритет над более общей привязкой. Без более конкретной информации о вашей проблеме мы не можем больше помочь. Опять же, если вы нажмете кнопку, чтобы отобразить диалоговое окно, и закроете диалоговое окно, фокус должен вернуться к кнопке. Фокус не переключается случайным образом на другой компонент. Если вы считаете, что он меняется случайным образом, опубликуйте минимальный воспроизводимый пример, демонстрирующий проблему.

camickr 21.03.2022 15:43

@camickr спасибо, это определенно помогает - я все еще получаю случаи, когда клавиша ESC где-то заканчивается. Судя по моим тестам, это происходит из-за нажатия команды на клавиатуре, а затем ее отмены с помощью ESC. или нажатие командной клавиши, щелчок мышью, а затем выход из состояния. Так что проблема где-то в коде моего приложения. Возвращаясь к первоначальному вопросу: как я могу отследить, какой компонент приложения находится в фокусе?

Snorik 21.03.2022 18:37
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
6
44
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я не совсем уверен, что вы пытаетесь с этим сделать, но чтобы ответить на ваш вопрос, вы можете добавить FocusListener к каждому элементу. Затем записывается avriable с использованием функции FocusGained.

int focus = 0;
textField1.addFocusListener(new FocusListener() {
        @Override
    
        public void focusGained(FocusEvent e) {
            focus = 1;                    
        }
    
        @Override
        public void focusLost(FocusEvent e) {
            
        }
    });

textField2.addFocusListener(new FocusListener() {
        @Override
    
        public void focusGained(FocusEvent e) {
            focus = 2;                    
        }
    
        @Override
        public void focusLost(FocusEvent e) {
            
        }
    });

Ах, да, это именно то, чего я пытался добиться более простым способом. Но я вообще не думал о том, чтобы сделать это таким образом. Спасибо, это поможет!

Snorik 21.03.2022 19:04

Таким образом, предполагаемым виновником была подсказка отладки. Их полное удаление и добавление кода Штеффи для ведения журнала убедили меня, что теперь проблема решена. Спасибо всем, я снова узнал что-то новое.

Другие вопросы по теме