-
Bug
-
Resolution: Fixed
-
P1
-
1.1
-
1.1.1
-
generic
-
windows_95
-
Not verified
/*
* Keyboard events on Win32, are eagerly bound to the current
* focus owner. If the user "types ahead" of the event dispatcher
* the new KeyEvents will be destined for the current focus component
* even though a KeyListener processing the current KeyEvent may
* eventually decide to change the focus.
*
* The application below demonstrates the problem. If you type "aTABb"
* (quickly) at the first textfield, the "b" should appear
* in the third textfield after a short delay. This works correctly
* on Motif, but not on Win32. I believe the only reason the Motif
* version works is that there's no real concurrency going on between
* The event dispatching loop and listener processing.
*/
import java.awt.*;
import java.awt.event.*;
public class XFocus extends Panel
{
TextField[] textFields = new TextField[3];
TextFieldListener textFieldListener = new TextFieldListener();
XFocus()
{
for(int i = 0; i < textFields.length; i++) {
textFields[i] = new TextField(10);
textFields[i].addFocusListener(textFieldListener);
textFields[i].addKeyListener(textFieldListener);
}
for(int i = 0; i < textFields.length; i++) {
add(textFields[i]);
}
}
public static void main(String[] args)
{
Frame f = new Frame("XFocus");
f.add(new XFocus());
f.pack();
f.show();
}
private final class TextFieldListener implements FocusListener, KeyListener
{
public void focusGained(FocusEvent e)
{
System.out.println(e);
}
public void focusLost(FocusEvent e)
{
System.out.println(e);
}
public void keyTyped(KeyEvent e)
{
System.out.println(e);
}
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_TAB) {
System.out.println("slowly validating ...");
try {
Thread.sleep(500);
}
catch(InterruptedException x) {
}
System.out.println("done validating ...");
getToolkit().beep();
e.consume();
textFields[textFields.length - 1].requestFocus();
}
}
public void keyReleased(KeyEvent e)
{
}
}
}
Original description from ORACLE:
Tabbing occurs irrespective of the sleep coded here to simulate validation
processing.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class TypeAhead
extends Applet
implements java.awt.event.KeyListener
{
TextField mTextField1;
TextField mTextField2;
TextField mTextField3;
public TypeAhead()
{
}
public static void main(String argv[])
{
Frame frame = new Frame();
Applet applet = new TypeAhead();
frame.setSize(300, 300);
frame.add(applet, "Center");
frame.show();
applet.start();
}
public void start()
{
setLayout(new GridLayout(0, 3));
mTextField1 = new TextField("f1");
mTextField1.addKeyListener(this);
mTextField2 = new TextField("f2");
mTextField2.addKeyListener(this);
mTextField3 = new TextField("f3");
mTextField3.addKeyListener(this);
add(mTextField1);
add(mTextField2);
add(mTextField3);
layout();
}
public void keyPressed(KeyEvent event)
{
printKeyEvent(event);
}
public void keyReleased(KeyEvent event)
{
printKeyEvent(event);
}
public void keyTyped(KeyEvent event)
{
if ( event.getKeyChar() == '\t' )
{
try
{
//
// Delay to simulate validation etc.
//
Thread.sleep(3000);
}
catch ( InterruptedException ie)
{
// ### ignore
}
}
printKeyEvent(event);
}
public void printKeyEvent(KeyEvent event)
{
System.out.println(event);
}
}
Checking/unchecking a checkbox delivers two itemStateChanged events on Win32
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class CheckboxItem
extends Applet
implements ItemListener
{
Checkbox mCheckbox;
public CheckboxItem()
{
}
public void start()
{
mCheckbox = new Checkbox("Checkbox");
mCheckbox.addItemListener(this);
add(mCheckbox);
}
public void itemStateChanged(ItemEvent event)
{
System.out.println("ItemEvent: " + event);
}
}
* Keyboard events on Win32, are eagerly bound to the current
* focus owner. If the user "types ahead" of the event dispatcher
* the new KeyEvents will be destined for the current focus component
* even though a KeyListener processing the current KeyEvent may
* eventually decide to change the focus.
*
* The application below demonstrates the problem. If you type "aTABb"
* (quickly) at the first textfield, the "b" should appear
* in the third textfield after a short delay. This works correctly
* on Motif, but not on Win32. I believe the only reason the Motif
* version works is that there's no real concurrency going on between
* The event dispatching loop and listener processing.
*/
import java.awt.*;
import java.awt.event.*;
public class XFocus extends Panel
{
TextField[] textFields = new TextField[3];
TextFieldListener textFieldListener = new TextFieldListener();
XFocus()
{
for(int i = 0; i < textFields.length; i++) {
textFields[i] = new TextField(10);
textFields[i].addFocusListener(textFieldListener);
textFields[i].addKeyListener(textFieldListener);
}
for(int i = 0; i < textFields.length; i++) {
add(textFields[i]);
}
}
public static void main(String[] args)
{
Frame f = new Frame("XFocus");
f.add(new XFocus());
f.pack();
f.show();
}
private final class TextFieldListener implements FocusListener, KeyListener
{
public void focusGained(FocusEvent e)
{
System.out.println(e);
}
public void focusLost(FocusEvent e)
{
System.out.println(e);
}
public void keyTyped(KeyEvent e)
{
System.out.println(e);
}
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_TAB) {
System.out.println("slowly validating ...");
try {
Thread.sleep(500);
}
catch(InterruptedException x) {
}
System.out.println("done validating ...");
getToolkit().beep();
e.consume();
textFields[textFields.length - 1].requestFocus();
}
}
public void keyReleased(KeyEvent e)
{
}
}
}
Original description from ORACLE:
Tabbing occurs irrespective of the sleep coded here to simulate validation
processing.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class TypeAhead
extends Applet
implements java.awt.event.KeyListener
{
TextField mTextField1;
TextField mTextField2;
TextField mTextField3;
public TypeAhead()
{
}
public static void main(String argv[])
{
Frame frame = new Frame();
Applet applet = new TypeAhead();
frame.setSize(300, 300);
frame.add(applet, "Center");
frame.show();
applet.start();
}
public void start()
{
setLayout(new GridLayout(0, 3));
mTextField1 = new TextField("f1");
mTextField1.addKeyListener(this);
mTextField2 = new TextField("f2");
mTextField2.addKeyListener(this);
mTextField3 = new TextField("f3");
mTextField3.addKeyListener(this);
add(mTextField1);
add(mTextField2);
add(mTextField3);
layout();
}
public void keyPressed(KeyEvent event)
{
printKeyEvent(event);
}
public void keyReleased(KeyEvent event)
{
printKeyEvent(event);
}
public void keyTyped(KeyEvent event)
{
if ( event.getKeyChar() == '\t' )
{
try
{
//
// Delay to simulate validation etc.
//
Thread.sleep(3000);
}
catch ( InterruptedException ie)
{
// ### ignore
}
}
printKeyEvent(event);
}
public void printKeyEvent(KeyEvent event)
{
System.out.println(event);
}
}
Checking/unchecking a checkbox delivers two itemStateChanged events on Win32
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class CheckboxItem
extends Applet
implements ItemListener
{
Checkbox mCheckbox;
public CheckboxItem()
{
}
public void start()
{
mCheckbox = new Checkbox("Checkbox");
mCheckbox.addItemListener(this);
add(mCheckbox);
}
public void itemStateChanged(ItemEvent event)
{
System.out.println("ItemEvent: " + event);
}
}