Философия Java

События и типы слушателей


Все компоненты 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)

    Это не полный список, частично потому, что событийная модель позволяет вам создавать вам свои собственные типы событий и ассоциированные слушатели. Таким образом, вы регулярно будете просматривать библиотеки, чтобы унаследовать свое собственное событие, и знания, полученные в этой главе, позволят вам понять, как использовать это события.

    Содержание раздела