Reputation: 77
Problem
I have two MouseEvent handlers (mouseClicked and mouseMoved), and they both work, but only separately.
If I click the mouse, the action gets processed fine. (bullet gets fired)
If I move the mouse, the action gets processed fine. (the sprite moves)
The problem occurs when I do both actions at the same time (moving mouse whilst clicking). The mouseMoved event goes through fine, but the mouseClicked event doesn't get called.
The below code is in my Game class constructor, which is extending JPanel.
this.addMouseListener(new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent e){
//This creates a new bullet, and adds to an array to get drawn.
bullet = new Bullet(105, e.getY()+5, bulletTexture);
bulletsOnScreen.add(bullet);
e.consume();
}
});
this.addMouseMotionListener(new MouseAdapter(){
@Override
public void mouseMoved(MouseEvent e){
//This increments the sprites position on the screen.
player.setYPosition(e.getY()-50);
e.consume();
};
});
What I've tried
I have tried using SwingWorker objects to run the mouseMoved in a background thread, but the results are the same (bullet doesn't fire).
@Override
public void mouseMoved(MouseEvent e){
SwingWorker myWorker = new SwingWorker<Void, Void>(){
@Override
protected Void doInBackground() throws Exception {
player.setYPosition(e.getY()-50);
e.consume();
return null;
}
};
myWorker.execute();
};
I have also tried to check for a mouseClick within the mouseMoved method, again to no success.
public void mouseMoved(MouseEvent e){
if(e.getButton() == MouseEvent.MOUSE_CLICKED){
//Create bullet and add to array (but this never gets called)
}
player.setYPosition(e.getY()-50);
e.consume();
};
If anyone has any ideas or pointers, it would be great thanks.
Upvotes: 2
Views: 976
Reputation: 3706
Here's some code I cooked to have full working example of behavior you described.
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
System.out.println("Pressed");
}
@Override
public void mouseClicked(MouseEvent e) {
System.exit(1);
}
});
frame.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
System.out.println("Moved");
}
});
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(100, 100);
frame.setVisible(true);
}
});
}
}
As you will see when moving around frame you will get lots of "Moved"
events.
Most interesting for you will be part that when you press mouse button down you will see "Pressed"
. If you release without moving there will be clicked event ( app will exit ). Closing app might be a bit extreme but we have to be sure that we don't miss that event.
But when you press down mouse button, hold it and move, you won't see any move event triggered. Then, when you release, you won't get clicked event fired either.
I'm not sure about this part but it looks like mouseClicked
will be triggered only if mousePressed
and mouseReleased
event occur one after another.
In your game, when you click and move your mouse at the same time you basically do
mousePressed -> mouseMoved -> mouseReleased
but this doesn't fire mouseClicked
as a result.
My advice on that would be that you handle mousePressed
instead of mouseClicked
or try to adapt MouseAdapter#mouseDragged
method to your needs.
Upvotes: 2