У меня возникают проблемы с определением, куда переходит фокус в моем приложении после активации/деактивации или открытия/закрытия некоторых диалогов.
Есть ли способ безопасно передать событие вниз по иерархии компонентов, чтобы получать информацию, когда фокус меняется и куда?
Например, в среде Smalltalk вы можете по причинам тестирования просто повторно реализовать #requestFocus на уровне Window/SubPane (т. е. JComponent) и иметь оператор отладки, куда переместился фокус.
Можете ли вы сделать что-то подобное на Java или есть какой-то механизм, который мне не хватает?
Итак, у меня есть InputMap/ActionMap, определенный для компонента. Это работает идеально большую часть времени. Однако у меня бывают ситуации, когда, например, событие клавиши ESC перехватывается где-то, что означает, что мне нужно несколько раз нажать ESC, чтобы приложение закрылось, и я действительно хотел бы знать, почему. У меня есть навязчивое подозрение, что Фокус уходит от Компонента, и я хотел бы в этом убедиться. Кроме того, я хотел бы узнать больше о том, как это работает в Swing. Спасибо, что указали на KeyBoardFocusManager, это уже выглядит действительно полезным.
@camickr спасибо - я дам обновление. Но все же хотелось бы понять, чем закончились события.
Swing использует привязки клавиш для всех своих компонентов. Таким образом, любой компонент, использующий привязку WHEN_IN_FOCUS, будет иметь приоритет над более общей привязкой. Без более конкретной информации о вашей проблеме мы не можем больше помочь. Опять же, если вы нажмете кнопку, чтобы отобразить диалоговое окно, и закроете диалоговое окно, фокус должен вернуться к кнопке. Фокус не переключается случайным образом на другой компонент. Если вы считаете, что он меняется случайным образом, опубликуйте минимальный воспроизводимый пример, демонстрирующий проблему.
@camickr спасибо, это определенно помогает - я все еще получаю случаи, когда клавиша ESC где-то заканчивается. Судя по моим тестам, это происходит из-за нажатия команды на клавиатуре, а затем ее отмены с помощью ESC. или нажатие командной клавиши, щелчок мышью, а затем выход из состояния. Так что проблема где-то в коде моего приложения. Возвращаясь к первоначальному вопросу: как я могу отследить, какой компонент приложения находится в фокусе?
Я не совсем уверен, что вы пытаетесь с этим сделать, но чтобы ответить на ваш вопрос, вы можете добавить 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) {
}
});
Ах, да, это именно то, чего я пытался добиться более простым способом. Но я вообще не думал о том, чтобы сделать это таким образом. Спасибо, это поможет!
Таким образом, предполагаемым виновником была подсказка отладки. Их полное удаление и добавление кода Штеффи для ведения журнала убедили меня, что теперь проблема решена. Спасибо всем, я снова узнал что-то новое.
Фокус возвращается к компоненту, который последним был в фокусе перед отображением другого окна. Не уверен, почему вы думаете, что вам нужно знать, какой компонент имеет фокус. Какую проблему вы пытаетесь решить? Может быть, вы можете использовать
WindowListner
, чтобы знать, когда окно активировано. Тогда, возможно, используйтеKeyBoardFocusManager
.