Диспетчеризация событий
Если вам понадобится обработать просто действие мыши, не важно, нажатие это, перемещение или еще что-нибудь, то придется включать эту обработку во все семь методов двух классов-слушателей событий мыши.
Эту работу можно облегчить, выполнив обработку не в слушателе, а на более ранней стадии. Дело в том, что прежде чем событие дойдет до слушателя, оно обрабатывается несколькими методами.
Чтобы в компоненте произошло событие AWT, должно быть выполнено хотя бы одно из двух условий: к компоненту присоединен слушатель или в конструкторе компонента определена возможность появления события методом enableEvents (). В аргументе этого метода через операцию побитового сложения перечисляются константы класса AWTEvent, задающие события, которые могут произойти в компоненте, например:
enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK I AWTEvent.KEY_EVENT_MASK)
При появлении события создается объект соответствующего класса xxxEvent. Метод dispatchEvent () определяет, где появилось событие – в компоненте или одном из его подкомпонентов, – и передает объект-событие методу processEvent () компонента-источника.
Метод processEvent () определяет тип события и передает его специализированному методу processxxxEvent (). Вот начало этого метода:
protected void processEvent(AWTEvent e){ if (e instanceof FocusEvent){ processFocusEvent((FocusEvent)e); }else if (e instanceof MouseEvent){ switch (e.getlDO) { case MouseEvent.MOUSE_PRESSED: case MouseEvent.MOUSE_RELEASED: case MouseEvent.MOUSE_CLICKED: case MouseEvent.MOUSE_ENTERED: case MouseEvent.MOUSE_EXITED: processMouseEvent((MouseEvent)e); break/case MouseEvent.MOUSE_MOVED: case MouseEvent.MOUSE_DRAGGED: processMouseMotionEvent((MouseEvent)e); break; } }else if (e instanceof KeyEvent){ processKeyEvent((KeyEvent)e); } //…
Затем в дело вступает специализированный метод, например, processKeyEvent (). Он-то и передает объект-событие слушателю. Вот исходный текст этого метода:
protected void processKeyEvent(KeyEvent e){ KeyListener listener = keyListener; if (listener!= null){ int id = e.getlDf); switch(id){ case KeyEvent.KEYJTYPED: listener.keyTyped(e); break; case KeyEvent.KEY_PRESSED: listener.keyPressed(e); break; case KeyEvent.KEY_RELEASED: listener.keyReleased(e); break; } } }
Из этого описания видно, что если вы хотите обработать любое событие типа AWTEvent, то вам надо переопределить метод processEvent (), а если более конкретное событие, например, событие клавиатуры, – переопределить более конкретный метод processKeyEvent (). Если вы не переопределяете весь метод целиком, то не забудьте в конце обратиться к методу суперкласса, например:
super.processKeyEvent(e);
Замечание
He забывайте обращаться к методу processXxxEvent() суперкласса.
В следующей главе мы применим такое переопределение в листинге 13.2 для вызова всплывающего меню.