События и типы слушателей
Все компоненты Swing включают методы addXXXListener( ) и removeXXXListener( ), так что подходящий тип слушателя может быть добавлен и удален для каждого компонента. Вы заметите, что “XXX” в каждом случае также представляет аргумент метода, например: addMyListener(MyListener m). Приведенная ниже таблица включает основные ассоциированные события, слушатели и методы, наряду с основными компонентами, которые поддерживают эти определенные события, обеспечивая методы addXXXListener( ) и removeXXXListener( ). Вы должны иметь в виду, что модель событий разработана для расширения, так что вы можете насчитать другие события и типы слушателей, не попавшие в эту таблицу.
Событие, интерфейс слушателя и методы добавления, удаления
Компоненты, поддерживающие это событие
ActionEvent
ActionListener
addActionListener( )
removeActionListener( ) |
JButton, JList, JTextField, JMenuItem и наследованные от них, включая JCheckBoxMenuItem, JMenu и JpopupMenu. |
AdjustmentEvent
AdjustmentListener
addAdjustmentListener( )
removeAdjustmentListener( ) |
JScrollbar и все, что вы создаете, реализуя Adjustable interface. |
|
ComponentEvent
ComponentListener
addComponentListener( )
removeComponentListener( ) |
*Component и наследованные от него, включая JButton, JCanvas, JCheckBox, JComboBox, Container, JPanel, JApplet, JScrollPane, Window, JDialog, JFileDialog, JFrame, JLabel, JList, JScrollbar, JTextArea и JTextField. |
ContainerEvent
ContainerListener
addContainerListener( )
removeContainerListener( ) |
Container и наследованные от него, включая JPanel, JApplet, JScrollPane, Window, JDialog, JFileDialog и JFrame. |
FocusEvent
FocusListener
addFocusListener( )
removeFocusListener( ) |
Component и унаследованные*. |
KeyEvent
KeyListener
addKeyListener( )
removeKeyListener( ) |
Component и унаследованные*. |
MouseEvent (для кликов и перемещений)
MouseListener
addMouseListener( )
removeMouseListener( ) |
Component и унаследованные*. |
MouseEvent[68] (для кликов и перемещений)
MouseMotionListener
addMouseMotionListener( )
removeMouseMotionListener( ) |
Component и унаследованные*. |
WindowEvent
WindowListener
addWindowListener( )
removeWindowListener( ) |
Window и унаследованные от него, включая JDialog, JFileDialog и JFrame. |
ItemEvent
ItemListener
addItemListener( )
removeItemListener( ) |
JCheckBox, JCheckBoxMenuItem, JComboBox, JList и все, что реализует ItemSelectable interface. |
TextEvent
TextListener
addTextListener( )
removeTextListener( ) |
Все, что унаследовано от JTextComponent, включая JTextArea и JTextField. |
<
Вы видите, что каждый тип компонент поддерживает только определенные типы событий. Оказывается, довольно трудно просмотреть все события, поддерживаемые компонентом. Простой подход - это изменение программы ShowMethodsClean.java из Главы 12, чтобы отобразить все слушатели событий, поддерживаемые компонентами Swing, которые вы вводите.
В Главе 12 была введена рефлексия, которая использовалась для поиска методов определенного класса — или всего списка методов или подмножества методов, имена которых содержат передаваемое вами ключевое слово. Магия этого в том, что так автоматически можно показать все методы класса без прохождения по иерархии наследования, проверяя классы на всех уровнях. Таким образом, это обеспечивает сохранение драгоценного времени при программировании: потому что имена большинства методов Java сделаны очень многозначительными и описательными, вы можете искать имена методов, содержащих определенное, интересующее вас слово. Когда вы найдете то, что вы искали, проверьте онлайн документацию.
Однако в Главе 12 не было Swing, поэтому инструментарий той главы был разработан как приложение для командной строки. Здесь более полезная GUI версия, специализирующаяся на поиске методов “addListener” в компонентах Swing:
//: c13:ShowAddListeners.java
// Отображение методов "addXXXListener" любого
// класса Swing.
// <applet code = ShowAddListeners
// width=500 height=400></applet>
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.lang.reflect.*; import java.io.*; import com.bruceeckel.swing.*; import com.bruceeckel.util.*;
public class ShowAddListeners extends JApplet { Class cl; Method[] m; Constructor[] ctor; String[] n = new String[0]; JTextField name = new JTextField(25); JTextArea results = new JTextArea(40, 65); class NameL implements ActionListener { public void actionPerformed(ActionEvent e) { String nm = name.getText().trim(); if(nm.length() == 0) { results.setText("No match"); n = new String[0]; return; } try { cl = Class.forName("javax.swing." + nm); } catch(ClassNotFoundException ex) { results.setText("No match"); return; } m = cl.getMethods(); // Преобразование в массив Strings:
n = new String[m.length]; for(int i = 0; i < m.length; i++) n[i] = m[i].toString(); reDisplay(); } } void reDisplay() { // Создание результирующего множества:
String[] rs = new String[n.length]; int j = 0; for (int i = 0; i < n.length; i++) if(n[i].indexOf("add") != -1 && n[i].indexOf("Listener") != -1) rs[j++] = n[i].substring(n[i].indexOf("add")); results.setText(""); for (int i = 0; i < j; i++) results.append( StripQualifiers.strip(rs[i]) + "\n"); } public void init() { name.addActionListener(new NameL()); JPanel top = new JPanel(); top.add(new JLabel( "Swing class name (press ENTER):")); top.add(name); Container cp = getContentPane(); cp.add(BorderLayout.NORTH, top); cp.add(new JScrollPane(results)); } public static void main(String[] args) { Console.run(new ShowAddListeners(), 500,400); } } ///:~
Класс StripQualifiers, определенный в Главе 12 здесь повторно используется, импортируясь из библиотеки com.bruceeckel.util.
GUI содержит JTextField name, в котором вы можете вводить имя класса Swing, который вы хотите просмотреть. Результат отображается в JTextArea.
Вы увидите, что нет никаких кнопок или других компонент, чтобы указать, что можно начать поиск. Это потому, что за JTextField следит ActionListener. Когда вы сделаете изменения и нажмете ENTER, список немедленно обновится. Если текст не пустой, он используется внутри Class.forName( ), чтобы попытаться найти класс. Если имя неверное, Class.forName( ) завершится неудачей, в результате чего появится исключение. Оно будет поймано и в JTextArea появится “No match”. Но если вы напечатаете корректное имя (включая большие буквы), Class.forName( ) завершится успешно и getMethods( ) вернет массив объектов Method. Каждый объект массива включается в String через toString( ) (так получается полная сигнатура метода) и добавляется в n - массив String. Массив n - это член класса ShowAddListeners, он используется при обновлении отображения, когда вызывается reDisplay( ).
reDisplay( ) создает массив String, называемый rs (для “result set”). Результирующее множество условно копируется из String в n, который содержит “add” и “Listener”. Затем используются indexOf( ) и substring( ) для удаления квалификаторов, таких как public, static и т.п. В конце StripQualifiers.strip( ) удаляет дополнительные квалификаторы имени.
Эта программа - это удобный способ для исследования совместимости компонент Swing. Как только вы узнаете, какие события поддерживает определенный компонент, вам не нужно будет искать ничего, чтобы отреагировать на это событие. Вы просто:
Берете имя класса события и удаляете слово “Event”. К остатку прибавляете слово “Listener”. Это интерфейс слушателя, который вы должны реализовать в вашем внутреннем классе.
Реализуете вышеупомянутый интерфейс и пишите методы для событий, который вы хотите отслеживать. Например, вы можете следить за движением мыши, тогда вы пишите код метода mouseMoved( ) из интерфейса MouseMotionListener. (Конечно, вы должны реализовать другие методы, но есть сокращения, которые вы скоро увидите.) Создаете объект класса слушателя из Шага 2. Регистрируете его в вашем компоненте с помощью метода, произведенного добавлением “add” к имени вашего слушателя. Например: addMouseMotionListener( ).
Вот некоторые из интерфейсов слушателя:
Интерфейс слушателя
w/ adapter
Методы интерфейса
| ActionListener |
actionPerformed(ActionEvent) |
| AdjustmentListener |
adjustmentValueChanged(
AdjustmentEvent) |
ComponentListener
ComponentAdapter |
componentHidden(ComponentEvent)
componentShown(ComponentEvent)
componentMoved(ComponentEvent)
componentResized(ComponentEvent) |
ContainerListener
ContainerAdapter |
componentAdded(ContainerEvent)
componentRemoved(ContainerEvent) |
FocusListener
FocusAdapter |
focusGained(FocusEvent)
focusLost(FocusEvent) |
KeyListener
KeyAdapter |
keyPressed(KeyEvent)
keyReleased(KeyEvent)
keyTyped(KeyEvent) |
MouseListener
MouseAdapter |
mouseClicked(MouseEvent)
mouseEntered(MouseEvent)
mouseExited(MouseEvent)
mousePressed(MouseEvent)
mouseReleased(MouseEvent) |
MouseMotionListener
MouseMotionAdapter |
mouseDragged(MouseEvent)
mouseMoved(MouseEvent) |
WindowListener
WindowAdapter |
windowOpened(WindowEvent)
windowClosing(WindowEvent)
windowClosed(WindowEvent)
windowActivated(WindowEvent)
windowDeactivated(WindowEvent)
windowIconified(WindowEvent)
windowDeiconified(WindowEvent) |
| ItemListener |
itemStateChanged(ItemEvent) |
Это не полный список, частично потому, что событийная модель позволяет вам создавать вам свои собственные типы событий и ассоциированные слушатели. Таким образом, вы регулярно будете просматривать библиотеки, чтобы унаследовать свое собственное событие, и знания, полученные в этой главе, позволят вам понять, как использовать это события.
Все публикации раздела