JDK-4700276 : Peers process KeyEvents before KeyEventPostProcessors
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2002-06-11
  • Updated: 2002-08-08
  • Resolved: 2002-08-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2 mantisFixed
Related Reports
Relates :  
Description

Name: osR10079			Date: 06/11/2002

This bug is about AWT-part of problem described in
4172991 (Win32 PLAF: Alt key must be pressed twice for focus toggle)

The notion of KeyEventPostProcessor was introduced to give user way to
process all KeyEvents after they have been dispatched by registered
listener.  KeyEventPostProcessor should be 
considered as last place to process KeyEvents on java-level.  And so
KeyEvents must be processed by peers only after post processors.  But
now AWT transfers KeyEvents to peers in Component.dispatchEvent()
which is called before post processors.

As result, even if post processor consumes an event, this event will
still be processed by peer as a non-consumed event.

Here is a testcase in which post processor consumes all ALT
presses and releases.
//************** ConsumedKeyEventTest.java
import java.awt.*;
import java.awt.event.*;

public class ConsumedKeyEventTest implements KeyEventPostProcessor
{
    public static void main(String[] args) {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().
            addKeyEventPostProcessor(new ConsumedKeyEventTest());
        Frame frame = new Frame("Main Frame");
        LWComponent comp = new LWComponent();
        Label label = new Label("The Label");
        label.setBackground(Color.RED);
        frame.setLayout(new FlowLayout());
        frame.add(label);
        frame.add(comp);
        frame.pack();
        System.err.println(comp.getPeer());

        MouseListener mouseListener = new FocusRequestor();
        label.addMouseListener(mouseListener);
        comp.addMouseListener(mouseListener);
        frame.addMouseListener(mouseListener);
        frame.setVisible(true);
    }

    public boolean postProcessKeyEvent(KeyEvent e) {
        System.err.println("postProcessor(" + e + ")");
        if (e.getKeyCode() == KeyEvent.VK_ALT) {
            System.err.println("\tconsumed");
            e.consume();
            return true;
        }
        return false;
    }

}

class LWComponent extends Component {
    LWComponent() {
        super();
        setSize(100, 100);
    }

    public Dimension getPreferredSize() {
        return new Dimension(100, 100);
    }

    public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, 100, 100);
    }
}

class FocusRequestor extends MouseAdapter {
    static int counter = 0;
    public void mouseClicked(MouseEvent me) {
        System.err.println(me);
        System.err.println("mouseClicked " + (counter++));
        me.getComponent().requestFocus();
    }
    public void mousePressed(MouseEvent me) {
        System.err.println(me);
    }
    public void mouseReleased(MouseEvent me) {
        System.err.println(me);
    }
}
//***** End of ConsumedKeyEventTest.java
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis FIXED IN: mantis INTEGRATED IN: mantis
24-08-2004

EVALUATION Name: osR10079 Date: 06/18/2002 To fix this bug i move peer's dispatching of KeyEvents from Component.dispatchEventImpl() to DefaultKeyboardFocusManager.dispatchKeyEvent(). ###@###.### June 19, 2002 ======================================================================
24-08-2004

SUGGESTED FIX Name: osR10079 Date: 06/18/2002 ###@###.### june 19, 2002 ------- Component.java ------- *** /tmp/dHwaiXg Fri Jun 7 16:37:44 2002 --- Component.java Fri Jun 7 16:02:01 2002 *************** *** 3652,3675 **** } /* ! * 9. Allow the peer to process the event. */ ! if (peer != null) { peer.handleEvent(e); } - - // Give native control a chance to dispatch the event if the focus - // owner is lightweight. Fix for 4390019 by ###@###.###. - if (e instanceof KeyEvent && - (peer == null || peer instanceof LightweightPeer)) { - Container target = getNativeContainer(); - if (target != null) { - ComponentPeer peer = target.getPeer(); - if (peer != null) { - peer.handleEvent(e); - } - } - } } // dispatchEventImpl() /* --- 3652,3665 ---- } /* ! * 9. Allow the peer to process the event. ! * Except KeyEvents, they will be processed by peer after ! * all KeyEventPostProcessors ! * (see DefaultKeyboardFocusManager.dispatchKeyEvent()) */ ! if (!(e instanceof KeyEvent) && (peer != null)) { peer.handleEvent(e); } } // dispatchEventImpl() /* ------- DefaultKeyboardFocusManager.java ------- *** /tmp/sccs.0gaajJ Thu Jun 13 15:21:25 2002 --- DefaultKeyboardFocusManager.java Thu Jun 13 15:17:25 2002 *************** *** 9,14 **** --- 9,16 ---- import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowEvent; + import java.awt.peer.ComponentPeer; + import java.awt.peer.LightweightPeer; import java.beans.PropertyChangeListener; import java.util.LinkedList; import java.util.Iterator; *************** *** 572,578 **** * been consumed, its target is enabled, and the focus owner is not null, * this method dispatches the event to its target. This method will also * subsequently dispatch the event to all registered ! * KeyEventPostProcessors. * <p> * In all cases, this method returns <code>true</code>, since * DefaultKeyboardFocusManager is designed so that neither --- 574,581 ---- * been consumed, its target is enabled, and the focus owner is not null, * this method dispatches the event to its target. This method will also * subsequently dispatch the event to all registered ! * KeyEventPostProcessors. After all this operations are finished, ! * the event is passed to peers for processing. * <p> * In all cases, this method returns <code>true</code>, since * DefaultKeyboardFocusManager is designed so that neither *************** *** 608,619 **** postProcessKeyEvent(e); } ! if (focusOwner == null) { ! java.awt.peer.ComponentPeer peer = e.getComponent().getPeer(); ! if (peer != null) { ! peer.handleEvent(e); } } return true; } --- 611,631 ---- postProcessKeyEvent(e); } ! // Allow the peer to process KeyEvent ! Component source = e.getComponent(); ! ComponentPeer peer = source.getPeer(); ! ! if (peer == null || peer instanceof LightweightPeer) { ! // if focus owner is lightweight then its native container ! // processes event ! Container target = source.getNativeContainer(); ! if (target != null) { ! peer = target.getPeer(); } } + if (peer != null) { + peer.handleEvent(e); + } return true; } *************** *** 635,641 **** Container p = (Container) (target instanceof Container ? target : target.getParent()); if (p != null) { ! p.postProcessKeyEvent((KeyEvent)e); } } return true; --- 647,653 ---- Container p = (Container) (target instanceof Container ? target : target.getParent()); if (p != null) { ! p.postProcessKeyEvent(e); } } return true; ======================================================================
24-08-2004