Обработка событий в Swing (переопределение через JFrame) - PullRequest
1 голос
/ 29 марта 2012

Насколько я понимаю, можно обрабатывать события через Swing, добавив Listener (например, MouseListener), используя метод addXXXListener компонента.

Предположим, я хочу для чего-либо перехватить ВСЕ события, которые получает Компонент (в моем случае, JFrame), и сделать с ними что-то общее, например.написать мой пользовательский диспетчер событий по любой причине.Один очень громоздкий и медленный способ сделать это - создать класс Listener, который прослушивает каждое отдельное событие и что-то с ними делает.

Однако я нашел более удачную идею: я расширилJFrame и переопределите processEvent (событие AWTEvent) следующим образом:

public class GameFrame extends JFrame
{
    public GameFrame(int width, int height)
    {
        super();
        //blah blah, stuff
        setVisible(true);
    }

    //override processEvent which is called in Component class every time an event happens
    @Override
    public void processEvent(AWTEvent event)
    {
        System.out.println("override " + event);
        //do whatever I want with my event here, then send it back up
        doSomething(event);
        super.processEvent(event);
    }
}

Идея состоит в том, что всякий раз, когда в JFrame происходит событие, будет вызываться processEvent, и я смогу получить событие прямо оттуда..

К сожалению, метод processEvent вызывается только с WindowEvents.MouseEvents и KeyEvents, похоже, не работают: когда я запускаю код, System.out.println выводит только WindowEvents.

Я думаю, я знаю причину - потому что в моем коде нет MouseListener,Компонент не потрудился вызвать processEvent, потому что нет MouseListeners.Так что я мог бы заставить этот код работать, если бы я создал и добавил в JFrame MouseListener, KeyListener ... и т. Д., Но это ничем не отличается от громоздкого и медленного метода, который я упоминал ранее.

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

1 Ответ

2 голосов
/ 29 марта 2012

Это потому, что JFrame поддерживает только два типа событий. В JFrame.java есть одна строка:

protected void frameInit() {
    enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);
    //other code here.
}

решение, как показано ниже, измените поведение JFrame, чтобы заставить его прослушивать MouseEvent и другое событие, которое вы называете (например, AWTEvent.MOUSE_MOTION_EVENT_MASK или MOUSE_WHEEL_EVENT_MASK)

enableEvents () находится в классе Component, и это защищенный метод, поэтому придется обходить его с помощью отражения.

public static void main(String[] args)
    throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
{
    JFrame frame = new GameFrame();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setSize(800, 600);

    frame.setVisible(true);
}

public static class GameFrame extends JFrame
{
    public GameFrame()
    {
        super();
        enableEvent(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
    }

    //override processEvent which is called in Component class every time an event happens
    @Override
    public void processEvent(AWTEvent event)
    {
        System.out.println("override " + event);
        super.processEvent(event);
    }

}
...