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
}

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

http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html
http://java.sun.com/docs/books/tutorial/uiswing/misc/keybinding.html

Комментариев: 9

9 Responses to “Swing focus”

Комментарии:

  1. corsair

    Судячі по кількості коментаріїв, то свінг тут не дуже шанують %))
    А взагалі хтось займається свінгом(це щоб писати GUI на яві, а не те що ви подумали %)) професійно? Чи є в києві компанії які свінгом заробляють собі на життя?

  2. Juriy

    >> Судячі по кількості коментаріїв, то свінг тут не дуже шанують
    Сейчас повальное увлечение Web-клиентами. C’est la vie.

    >> А взагалі хтось займається свінгом
    Ну вот, собственно, я и занимаюсь.

    >> Чи є в києві компанії які свінгом заробляють собі на життя?
    Думаю, в масштабах компаний ставить вопрос несколько неправильно. В Киеве есть компании, в которых есть проекты, которые активно используют Swing. К примеру – проект на котором сейчас я работаю ;-)

  3. Артем Волхонский

    Если кому будет интересно почитать про Swing есть книжка
    Герберт Шилдт – Swing: руководство для начинающиx
    http://rapidshare.com/files/133040933/002539.rar

  4. Juriy

    Раз пошла такая пьянка…
    Лучшая книга, которую я когда-нибудь читал по этой теме – “Filthy Rich Clients”, правда чтобы получить от нее максимум пользы основы Swing лучше все же знать. Если дойдут руки, напишу заметку-обзор.
    Есть еще несколько книг, которые не несут большой смысловой нагрузки, но хороши как справочники. К таким относятся, к примеру “The Definitive Guide to Java Swing”, автор John Zukowsky (у меня третье издание). Пару раз выручала.

  5. Vadim Voituk

    Juriy,
    Именно “Filthy Rich Clients” вдохновила одного из разработчиков Groovy написать переписать SwingBuilder и создать с GraphicsBuilder :)

  6. Артем Волхонский

    Я вот понять пытаюсь это опять спам?

  7. Vadim Voituk

    Артем,
    У тебя ещё есть сомнения по этому поводу? :)
    Так и вижу как барышня, раскручивающая сайт-сателит про Энджи, будет делать нам (!!!) “сайтик с форумом, галлерей”

  8. Артем Волхонский

    Я бы этой барышне с большими ушами, уши бы и пооткручивал

  9. Vadim Voituk

    :)

Leave a Reply