Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent robot.mouseMove to generate a MouseEvent?

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!

like image 932
thetheodor Avatar asked Nov 30 '25 14:11

thetheodor


2 Answers

I prefer code like the following:

component.removeMouseListener(...);
Robot.doSomething();
component.addMouseListener(...);

instead of setting a flag. Using this approach the code to manage the listener is in a single place in your code.

If you use a flag you need to

  1. define the flag variable,
  2. set/reset the variable
  3. test the variable

so you end up having code in multiple places in your class.

Edit:

Good point about the Robot being added to the end of the event queue. So, I would then wrap the code that adds the MouseListener back to the component in a SwingUtilities.invokeLater()

like image 86
camickr Avatar answered Dec 03 '25 04:12

camickr


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...

enter image description here

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();
        }
    }
}
like image 39
MadProgrammer Avatar answered Dec 03 '25 04:12

MadProgrammer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!