I have a 3D game, and every time I move the cursor, I want it to reset to the middle. Problem is that robot.mouseMove() calls MouseEvent (It does make sense) and resets the position and so I can't rotate.
Thank you!
Because Robot
is generating a native event, the event will (eventually) make it's way to the Event Queue for processing by the EDT.
This means if you try and do something like...
removeMouseListener(...);
Robot.mouseMove(...);
addMouseListener(...);
It will, basically, have no effect, as the removal and additional of the mouse listener have occurred in the same cycle of the event processing, meaning the mouse event that the robot has raised will not have being processed (or will appear later in the queue)...
Instead, you need to raise some kind of flag that you can detect and then ignore the next incoming event...
if (!ignoreMouseMove) {
ignoreMouseMove = true;
// Do your normal processing...
robot.mouseMove(...);
} else {
ignoreMouseMove = false;
}
The basic example below detects the distance from the center a mouse has moved and updates a simple position
variable (which basically acts as a compass point). This helps illustrate the movement, but more importantly, that we are breaking the event cycle...
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Robot;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestMouseMove {
public static void main(String[] args) {
new TestMouseMove();
}
public TestMouseMove() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Robot bot;
private int position = 0;
public TestPane() {
try {
bot = new Robot();
MouseAdapter ma = new MouseAdapter() {
boolean ignoreMouseMove = false;
@Override
public void mouseMoved(MouseEvent e) {
if (!ignoreMouseMove) {
ignoreMouseMove = true;
int x = getLocationOnScreen().x + (getWidth() / 2);
int y = getLocationOnScreen().y + (getHeight() / 2);
int distanceFromCenter = e.getPoint().x - (getWidth() / 2);
position += distanceFromCenter;
if (position < 0) {
position = 360 - position;
} else if (position > 360) {
position -= 360;
}
repaint();
bot.mouseMove(x, y);
} else {
ignoreMouseMove = false;
}
}
@Override
public void mouseClicked(MouseEvent e) {
System.exit(0);
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
} catch (AWTException ex) {
ex.printStackTrace();;
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
FontMetrics fm = g2d.getFontMetrics();
int x = getWidth() / 2;
int y = getHeight() / 2;
int amount = position;
while (x > 0) {
if (amount == position) {
g2d.drawLine(x, y, x, y - 40);
} else {
g2d.drawLine(x, y, x, y - 20);
}
String text = Integer.toString(amount);
g2d.drawString(text, x - (fm.stringWidth(text) / 2), y + fm.getHeight());
x -= 20;
amount--;
if (amount < 0) {
amount = 360 + amount;
}
}
amount = position + 1;
x = (getWidth() / 2) + 20;
while (x < getWidth()) {
g2d.drawLine(x, y, x, y - 20);
if (position > 360) {
position = 360 - position;
}
String text = Integer.toString(amount);
g2d.drawString(text, x - (fm.stringWidth(text) / 2), y + fm.getHeight());
x += 20;
amount++;
}
g2d.dispose();
}
}
}