Swing focus
Рубрика: Java | 28 August 2008, 13:24 | juriy
Небольшой рецепт для авторов собственных Swing компонентов.
Свои компоненты, как правило, наследуются непосредственно от JComponent. Самый простой компонент выглядит так:
JComponent comp = new JComponent(){};
Немного усложним задачу: предположим, нам нужно создать компонент, который должен получать уведомления о событиях клавиатуры. Нет ничего проще: в JComponent’е есть метод addKeyListener, который позволяет реализовать этот функционал:
class KeyAwareComponent extends JComponent implements KeyListener {
public KeyAwareComponent() {
addKeyListener(this);
}
public void keyPressed(KeyEvent e) {
System.out.println("Key Pressed");
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
Можно теперь добавить этот компонент на фрейм и порадоваться тому, как замечательно он игнорирует любые нажатия клавиш.
Проблема заключается в том, что Swing передает события клавиатуры компоненту, который в данный момент держит фокус. А JComponent по умолчанию вообще на фокус не претендует (другими словами, система передачи фокуса игнорирует этот компонент). Для полноты картины, следует заметить, что события мыши передаются в любом случае. То есть, если все взаимодействие с компонентом будет осуществляться мышью, то фокусничать не придется.
Решается проблема просто: в конструктор компонента нужно добавить еще одну строку:
class KeyAwareComponent extends JComponent implements KeyListener {
public KeyAwareComponent() {
addKeyListener(this);
setFocusable(true);
}
...
}
Теперь компонент будет бодро отзываться на нажатия клавиш. Осталась вторая проблема: перейти на компонент можно только клавишей Tab. По умолчанию клик по компоненту не является поводом передать ему фокус. Берем в руки напильник и “доводим до готовности” код:
class KeyAwareComponent extends JComponent
implements KeyListener, MouseListener {
public KeyAwareComponent() {
addKeyListener(this);
addMouseListener(this);
setFocusable(true);
}
public void keyPressed(KeyEvent e) {
System.out.println("Key Pressed");
}
public void mouseClicked(MouseEvent e) {
requestFocusInWindow();
}
// Тут - пустые методы, которые нас обязывают переопределить
// интерфейсы
}
Этот метод наиболее понятен и прост. Если есть желание поэкспериментировать, можно почитать tutorial от Sun и достичь того же эффекта несколько другим способом: добавить в inputMap компонента некоторый элемент:
class KeyAwareComponent extends JComponent
implements KeyListener {
public KeyAwareComponent() {
addKeyListener(this);
getInputMap(WHEN_FOCUSED).put(
KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0),
"someAction");
}
// Тут - пустые методы, которые нас обязывает переопределить
// KeyListener
}
Кода существенно меньше, работает так же хорошо, как и первый метод, но не так очевидно достигает нужного результата.
Вот полезные ссылки по теме:

Судячі по кількості коментаріїв, то свінг тут не дуже шанують %))
А взагалі хтось займається свінгом(це щоб писати GUI на яві, а не те що ви подумали %)) професійно? Чи є в києві компанії які свінгом заробляють собі на життя?
>> Судячі по кількості коментаріїв, то свінг тут не дуже шанують
Сейчас повальное увлечение Web-клиентами. C’est la vie.
>> А взагалі хтось займається свінгом
Ну вот, собственно, я и занимаюсь.
>> Чи є в києві компанії які свінгом заробляють собі на життя?
Думаю, в масштабах компаний ставить вопрос несколько неправильно. В Киеве есть компании, в которых есть проекты, которые активно используют Swing. К примеру – проект на котором сейчас я работаю ;-)
Если кому будет интересно почитать про Swing есть книжка
Герберт Шилдт – Swing: руководство для начинающиx
http://rapidshare.com/files/133040933/002539.rar
Раз пошла такая пьянка…
Лучшая книга, которую я когда-нибудь читал по этой теме – “Filthy Rich Clients”, правда чтобы получить от нее максимум пользы основы Swing лучше все же знать. Если дойдут руки, напишу заметку-обзор.
Есть еще несколько книг, которые не несут большой смысловой нагрузки, но хороши как справочники. К таким относятся, к примеру “The Definitive Guide to Java Swing”, автор John Zukowsky (у меня третье издание). Пару раз выручала.
Juriy,
Именно “Filthy Rich Clients” вдохновила одного из разработчиков Groovy написать переписать SwingBuilder и создать с GraphicsBuilder :)
Я вот понять пытаюсь это опять спам?
Артем,
У тебя ещё есть сомнения по этому поводу? :)
Так и вижу как барышня, раскручивающая сайт-сателит про Энджи, будет делать нам (!!!) “сайтик с форумом, галлерей”
Я бы этой барышне с большими ушами, уши бы и пооткручивал
:)