How to redirect ANY AWTEvent in java?

I have a function to implement in a Java 1.5 Swing application. If a specific exception occurs during AWTEvent processing, I must open an alternative form, solve the problem, and continue processing the source event. When I rewrite an event into a component, nothing happens. When I click on an event in the event queue, nothing happens. I assume that there are some status fields in the event that mark it as processed, so the components do not pick it up. So far I can’t find a way to recreate the clone of the event. And the custom event will not help here, because I want the previous event to be processed.

In the swing application, the existing event queue is replaced by the internal queue.

private class ApplicationEventQueue extends EventQueue  
{  
    private final ArrayList listeners=new ArrayList();  
    protected void initialize()  
    {  
        Toolkit.getDefaultToolkit().getSystemEventQueue().push(this);  
    }
.
.
.
}

, . , " ".

@Override  
protected void dispatchEvent(AWTEvent event)  
{  
    try  
    {  
        super.dispatchEvent(event);  
        if (peekEvent() != null && userEventDispatched)  
        {  
            raiseIdleEvent();  
            userEventDispatched = false;  
        }  
        else  
        {  
            int eventId = event.getID();  
            if (eventId == KeyEvent.KEY_TYPED || eventId == MouseEvent.MOUSE_CLICKED)  
            {  
                userEventDispatched = true;  
            }  
        }  
    }  
    catch (Throwable ex)  
    {  
        onError(ex);  
    }  
}

- . , . - , , . : onError , . , , , . , , , , .

  • ( ).
  • , .
  • , AWTEvent.
  • , , .
  • , .

, . .

: . ( ) , . . . .

, , , , , , .

+3
3

. .

(X), . , Y, . Y .

: X , , Y GUI, Y .

Update:

, SwingWorker bg. ChangeEvent EDT . SwingWorker publish/process . SwingWorker , , .

class Test extends JPanel {
    private JButton b;
    public Test() {
        b = new JButton(new AbstractAction("Do something") {
            @Override
            public void actionPerformed(ActionEvent e) {
                final JButton btn = (JButton) e.getSource();
                btn.setEnabled(false);
                Object req = new Object(); // Replace w/ apropriate type
                new RequestDispatch(req, new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        final Object req = e.getSource();
                        // Do something with data from 'req'
                        btn.setEnabled(true);
                    }
                });
            }
        });
        add(b);
    }
}

class RequestDispatch extends SwingWorker<Object, Void> {
    private enum DispatchState { Ready, Running, Canceled }
    private final ChangeListener listener;
    private DispatchState dstate = DispatchState.Ready;
    private final Object req;
    RequestDispatch(Object req, ChangeListener listener)
    {
        this.req = req;
        this.listener = listener;
        execute();
    }
    @Override
    protected Object doInBackground() throws Exception {
        while (true) {
            DispatchState st = getDState();
            if (st == DispatchState.Ready)
            {
                try {
                    setDstate(DispatchState.Running);
                    // send request to the server, update req with response
                    return req;
                }
                catch (TimeoutException ex) {
                    this.publish((Void)null);
                    synchronized (this) {
                        wait();
                    }
                }
            }
            if (st == DispatchState.Canceled) {
                return req;
            }
        }
    }
    @Override
    protected void process(List<Void> chunks) {
        // Session has timed out
        // Ask the user to re-authenticate
        int result = JOptionPane.showConfirmDialog(null, "Login");
        if (result == JOptionPane.CANCEL_OPTION) {
            setDstate(DispatchState.Canceled);
        }
        else {
            setDstate(DispatchState.Ready);
        }
    }
    private synchronized DispatchState getDState() {
        return dstate;
    }
    private synchronized void setDstate(DispatchState dstate) {
        this.dstate = dstate;
        notifyAll();
    }
}
+2

- AWTEventWrapper, AWTEvent. , consume() isConsumed() ( ), , , .

+1

JDK6, AWTEvent.consumed false, consume(), no unconsume().

, OP own # 5 - , . ( , AWTEvent#get_InputEvent_CanAccessSystemClipboard().)

In onError()you can create another event queue that overrides the getNextEventplus logical flag, so when you call EventQueue#push(), the new queue will contain all the current events in the list, then make an error notification, finally put a new queue, flip consumedin case it selected an exception, repeat it, and then previous events stored in the list.

0
source

Source: https://habr.com/ru/post/1751566/


All Articles