Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2030676 | 1.4.0 | Uwe Uwe | P2 | Resolved | Fixed | beta |
To reproduce, run the test case, and click in the text field.
Hold down the Shift key, and quickly hit the F1 key at least twenty times,
then let go of the Shift key. For each keystroke, you'll see a printout
saying whether the Shift key modifier was present or not. Because it
will take the system a while to repaint all the buttons, the printouts
will keep coming even after you're done typing. The expected behavior is that
the printout will display "Shift = true" for each keystroke. The actual behavior is that after some number of iterations the printout will start to
incorrectly display "shift = false".
The number of iterations before this occurs will vary according to your hardware configuration and JDK version. On a PII 450 machine, I have seen the failure
occur after two keystrokes with 1.2.2, but only after at least 18 or 20 keystrokes with the latest build of 1.3. I believe that the problem is partially masked by the increased speed of 1.3.
The customer believes this problem is not limited to key events:
"I believe that this or a similar bug causes problems with JButtons too.
It is surprisingly common to think you've clicked a JButton, but that
JButton's action is not actually performed. I've never seen this happen
with AWT Buttons. I suspect that what's going on is that the user presses
and releases the mouse on the JButton, and then moves the mouse off the
button. By the time the event system delivers the MouseReleased message
to the button, the mouse is no longer over the button, and the VM
incorrectly gives the coordinates of the MouseReleased as the current
coordinates of the mouse, instead of the coordinates of where the mouse
was when the mouse button was released. This causes the JButton not
to fire."
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ModifiersTest implements KeyListener
{
public final static void main (String[] args)
{
ModifiersTest test = new ModifiersTest();
// Create a frame
JFrame f = new JFrame("hi");
f.getContentPane().setLayout(null);
f.setBounds(100,100,600,200);
// Add a text field
JTextField t = new JTextField();
t.setBounds(30,30,70,30);
t.addKeyListener(test);
f.getContentPane().add(t);
// Add a whole bunch of buttons, to slow down painting.
for (int j = 0; j < 10; j++)
{
for (int i = 0; i < 20; i++)
{
for (int k = 0; k < 20; k++)
{
JButton b = new JButton();
b.setBounds(i * 30 + j*2, 100 + j*2, 25, 25);
b.setText("hi");
f.getContentPane().add(b);
}
}
}
// show the frame.
f.show();
}
public void keyPressed(KeyEvent e)
{
// See if the user pressed F1
if (e.getKeyCode() == KeyEvent.VK_F1)
{
// Print out the modifiers.
int modifiers = e.getModifiers();
boolean shift = ((modifiers & InputEvent.SHIFT_MASK) != 0);
System.out.println("shift = " + shift);
// Call paintImmediately on the content pane.
JComponent component = (JComponent)e.getSource();
JComponent parent = (JComponent)component.getParent();
parent.paintImmediately(parent.getBounds());
// (Or you can call repaint() instead
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
Hold down the Shift key, and quickly hit the F1 key at least twenty times,
then let go of the Shift key. For each keystroke, you'll see a printout
saying whether the Shift key modifier was present or not. Because it
will take the system a while to repaint all the buttons, the printouts
will keep coming even after you're done typing. The expected behavior is that
the printout will display "Shift = true" for each keystroke. The actual behavior is that after some number of iterations the printout will start to
incorrectly display "shift = false".
The number of iterations before this occurs will vary according to your hardware configuration and JDK version. On a PII 450 machine, I have seen the failure
occur after two keystrokes with 1.2.2, but only after at least 18 or 20 keystrokes with the latest build of 1.3. I believe that the problem is partially masked by the increased speed of 1.3.
The customer believes this problem is not limited to key events:
"I believe that this or a similar bug causes problems with JButtons too.
It is surprisingly common to think you've clicked a JButton, but that
JButton's action is not actually performed. I've never seen this happen
with AWT Buttons. I suspect that what's going on is that the user presses
and releases the mouse on the JButton, and then moves the mouse off the
button. By the time the event system delivers the MouseReleased message
to the button, the mouse is no longer over the button, and the VM
incorrectly gives the coordinates of the MouseReleased as the current
coordinates of the mouse, instead of the coordinates of where the mouse
was when the mouse button was released. This causes the JButton not
to fire."
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ModifiersTest implements KeyListener
{
public final static void main (String[] args)
{
ModifiersTest test = new ModifiersTest();
// Create a frame
JFrame f = new JFrame("hi");
f.getContentPane().setLayout(null);
f.setBounds(100,100,600,200);
// Add a text field
JTextField t = new JTextField();
t.setBounds(30,30,70,30);
t.addKeyListener(test);
f.getContentPane().add(t);
// Add a whole bunch of buttons, to slow down painting.
for (int j = 0; j < 10; j++)
{
for (int i = 0; i < 20; i++)
{
for (int k = 0; k < 20; k++)
{
JButton b = new JButton();
b.setBounds(i * 30 + j*2, 100 + j*2, 25, 25);
b.setText("hi");
f.getContentPane().add(b);
}
}
}
// show the frame.
f.show();
}
public void keyPressed(KeyEvent e)
{
// See if the user pressed F1
if (e.getKeyCode() == KeyEvent.VK_F1)
{
// Print out the modifiers.
int modifiers = e.getModifiers();
boolean shift = ((modifiers & InputEvent.SHIFT_MASK) != 0);
System.out.println("shift = " + shift);
// Call paintImmediately on the content pane.
JComponent component = (JComponent)e.getSource();
JComponent parent = (JComponent)component.getParent();
parent.paintImmediately(parent.getBounds());
// (Or you can call repaint() instead
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
- backported by
-
JDK-2030676 win32: Modifiers are Not Delivered Properly with Events
- Resolved
- duplicates
-
JDK-4362557 awt_Component::GetJavaModifiers() should use GetKeyState() not GetAsyncKeyState(
- Closed