Reputation: 9
On my Windows 8 system running Java 1.7 I found that key events are interfering with mouse events. Here's an example. This is a silly thing to do, but it illustrates the problem that has shown up in more complicated settings. I find that once I have pressed a key, I can't move the mouse until I release the key. I don't know of any reason why this shouldn't work.
In fact, a bit more experimenting shows that this doesn't seem to be a Java issue at all - so I'm not sure what I should do about this question in the forum.
As MadProgrammer stated below, it's a keyboard autorepeat issue. In fact, if you press a key and then quickly move the mouse (before the autorepeat kicks in) you can draw a short line. So, the key events from the autorepeat seem to block the mouse movement on the screen. This appears to happen throughout the Windows interface. For instance, I used the Accessibility settings to turn off autorepeat - so in NotePad, say, keys no longer repeat when held. However, if you hold a key, the mouse still locks up. It locks even if it isn't in the NotePad window.
Clearly this is not a Java issue - I just happened to notice it here.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// Demo key/mouse event interference
// Pressing and holding any key, moving the mouse
// and releasing the key should draw a line.
// written by mcslattery - april 2015
public class KeyMouse extends JPanel {
public static final int WID = 500;
public static final int HT = 400;
int x1,y1,x2,y2;
boolean drawn = false;
int mx,my;
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new KeyMouse()); f.pack();
f.setVisible(true);
}
public KeyMouse() {
super();
setPreferredSize(new Dimension(WID, HT));
addMouseMotionListener(new MseL());
addKeyListener(new KeyL());
setFocusable(true); requestFocus();
}
public void paintComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0,0,WID,HT);
if (drawn) {
g.setColor(Color.black);
g.drawLine(x1, y1, x2, y2);
}
}
class MseL extends MouseMotionAdapter {
public void mouseMoved(MouseEvent e) {
mx = e.getX(); my = e.getY();
}
}
class KeyL extends KeyAdapter {
public void keyPressed(KeyEvent e) {
x1 = mx; y1 = my;
drawn = false;
repaint();
}
public void keyReleased(KeyEvent e) {
x2 = mx; y2 = my;
drawn = true;
repaint();
}
}
}
Upvotes: 0
Views: 522
Reputation: 347214
The problem isn't with the OS or Java, it's with you assumption about how keyPressed
works.
When pressed, a key will trigger a keyPressed
event, after a OS specific delay, it will trigger repeated events until the key is released, when keyReleased
is called.
This means that...
public void keyPressed(KeyEvent e) {
x1 = mx;
y1 = my;
drawn = false;
repaint();
}
is constently updating the x1
and y1
values to be the same as the current mouse position...
Instead, add a flag which can be used to determine if the key has already been pressed, if it hasn't set the start values. When released, reset the flag, for example...
private boolean pressed = false;
public void keyPressed(KeyEvent e) {
if (!pressed) {
pressed = true;
x1 = mx;
y1 = my;
drawn = false;
repaint();
}
}
public void keyReleased(KeyEvent e) {
pressed = false;
Side note:
I'm not particular conformatable with your paintComponent
method...
public void paintComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0,0,WID,HT);
Three main reasons...
WID
wide or HT
heighsetBackground(Color.WHITE)
in the constructor and super.paintComponent(g)
to get the same results, which would generally be safer if paintComponent
changes for some reasonpublic
, you never want anyone to call itUpvotes: 1