Capturing (trapping) a mouse cursor in a window in Java

I am looking for a way to capture or capture a mouse in a window after it has entered this window, similar to how the mouse entered the virtual machine window until the user press CTRL + ALT + DEL or release the mouse in some other way. How to do it in Java? Switching to full screen is not an option.

EDIT:

Here are some SSCCEs for ya. This code will mask your mouse in the window. To exit, you only need to generate a frame and go directly to the close button. If you notice when your mouse tries to leave, it will automatically return to (0,0). I need to know how to make him return to the coordinates where he came from. I tried getX () and getY () instead of (0,0), but the robot does not return the mouse there (I think the response time should slow down). I also had a robot that takes the mouse back to crosshair.x and crosshair.y, but this one (like the others) still allows the mouse to exit if the user clicks at the right time. Any suggestions?

Main class:

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferStrategy;
import java.awt.image.MemoryImageSource;
import java.awt.Point;
import java.awt.Robot;
import java.awt.Toolkit;
import javax.swing.JFrame;

public class Game extends JFrame implements MouseMotionListener, MouseListener{

    private int windowWidth = 640;
    private int windowHeight = 480;
        private Crosshair crosshair;

    public static void main(String[] args) {
        new Game();
    }

    public Game() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(windowWidth, windowHeight);
        this.setResizable(false);
        this.setLocation(0,0);
        this.setVisible(true);

        this.createBufferStrategy(2);
                addMouseMotionListener(this);
                addMouseListener(this);
        initGame();

        while(true) {
            long start = System.currentTimeMillis();
            gameLoop();
            while(System.currentTimeMillis()-start < 5) {
                            //empty while loop
            }
        }
    }

    private void initGame() {
            hideCursor();
            crosshair = new Crosshair (windowWidth/2, windowHeight/2);
    }

        private void gameLoop() {
            //game logic
            drawFrame();
        }

        private void drawFrame() {

            BufferStrategy bf = this.getBufferStrategy();
            Graphics g = (Graphics)bf.getDrawGraphics();
            try {
                g = bf.getDrawGraphics();
                Color darkBlue = new Color(0x010040);
                g.setColor(darkBlue);
                g.fillRect(0, 0, windowWidth, windowHeight);
                drawCrossHair(g);
            } finally {
                g.dispose();
            }
            bf.show();
            Toolkit.getDefaultToolkit().sync();
        }

        private void drawCrossHair(Graphics g){
            Color yellow = new Color (0xEDFF62);
            g.setColor(yellow);
            g.drawOval(crosshair.x, crosshair.y, 40, 40);

            g.fillArc(crosshair.x + 10, crosshair.y + 21 , 20, 20, -45, -90);
            g.fillArc(crosshair.x - 1, crosshair.y + 10, 20, 20, -135, -90);
            g.fillArc(crosshair.x + 10, crosshair.y - 1, 20, 20, -225, -90);
            g.fillArc(crosshair.x + 21, crosshair.y + 10, 20, 20, -315, -90);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
        //empty method
        }

        @Override
        public void mouseMoved(MouseEvent e) {
        crosshair.x = e.getX();
        crosshair.y = e.getY();
        }

        private void hideCursor() {
            int[] pixels = new int[16 * 16];
            Image image = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(16, 16, pixels, 0, 16));
            Cursor transparentCursor = Toolkit.getDefaultToolkit().createCustomCursor(image, new Point(0, 0), "invisiblecursor");
            getContentPane().setCursor(transparentCursor);
    }

        public void mouseExited(MouseEvent e) {
            System.out.println("Event: " + e);
            try {
                Robot robot = new Robot();
                robot.mouseMove(0, 0);// When I use (getX(),getY()) instead of (0,0) the robot will not move the mouse at all even though getX() and getY() are the coordinates I want the mouse to be moved to.  Also the mouse can still escape, even when crosshair.x and crosshair.y are used as the coordinates.  It seems that robot is too slow.
            }
            catch (AWTException ex) {
                ex.printStackTrace();
            }
        }

        public void mouseEntered(MouseEvent e){
        }

        public void mousePressed(MouseEvent e) {
        }

        public void mouseReleased(MouseEvent e) {
        }

        public void mouseClicked(MouseEvent e) {
        }
}

Another class:

public class Crosshair{
        public int x;
    public int y;
    public Crosshair(int x, int y) {
        this.x = x;
        this.y = y;
        }
}
+3
source share
3 answers

, Global Event Listener . , Robot reset , .

+4

, , , , ( , ) . , .

CPU 50% - while, , . Thread, 5 , 5 , 18%.

, Swing. , 1%, .

. , , drawFrame().

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.image.BufferStrategy;

import javax.swing.*;

public class Game3 extends JFrame {

    /**
     * @author Georgi Khomeriki
     */

    private Ball ball;

    // added this
    private JPanel gamePanel;

    private int windowWidth = 800;
    private int windowHeight = 600;


    public static void main(String[] args) {
        new Game3();
    }

    public Game3() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(windowWidth, windowHeight);
        this.setResizable(false);
        this.setLocation(100, 100);
        this.setVisible(true);

        this.createBufferStrategy(2);

        initGame3();
/*
        while(true) {
            long start = System.currentTimeMillis();
            gameLoop();
            while(System.currentTimeMillis()-start < 5) {
                 //do nothing
            }
        }
*/

        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                while(true)
                {
                    gameLoop();
                    try { Thread.sleep(5); }
                    catch(Exception e) {}
                }
            }
        });
        thread.start();

    }

    private void initGame3() {
        // all you're game variables should be initialized here
        ball = new Ball(windowWidth/2, windowHeight/2, 5, 5);

        // added these lines

        gamePanel = new GamePanel();
        gamePanel.setBackground(Color.BLACK);
        add(gamePanel);
    }

    private void gameLoop() {
        // your game logic goes here

// move the ball
    ball.x = ball.x + ball.dx;
    ball.y = ball.y + ball.dy;

    // change the direction of the ball if it hits a wall
    if(ball.x <= 0 || ball.x >= windowWidth-40)
        ball.dx = -ball.dx;
    if(ball.y <= 0 || ball.y >= windowHeight-40)
        ball.dy = -ball.dy;


        // changed to following to use Swing instead of buffer strategy
//      drawFrame();
        gamePanel.repaint();
    }

    private void drawFrame() {
        // code for the drawing goes here
        BufferStrategy bf = this.getBufferStrategy();
        Graphics g = null;

        try {
            g = bf.getDrawGraphics();

            // clear the back buffer (just draw a big black rectangle over it)
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, windowWidth, windowHeight);

drawBall(g);


        } finally {
            // It is best to dispose() a Graphics object when done with it.
            g.dispose();
        }

        // Shows the contents of the backbuffer on the screen.
        bf.show();

        //Tell the System to do the Drawing now, otherwise it can take a few extra ms until
        //Drawing is done which looks very jerky
        Toolkit.getDefaultToolkit().sync();
    }

    private void drawBall(Graphics g) {

        g.setColor(Color.GREEN);
        g.fillOval(ball.x, ball.y, 40, 40);
    }

    // added this

    class GamePanel extends JPanel
    {
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            drawBall(g);
        }
    }


    class Ball {

        public int x;
        public int y;
        public int dx;
        public int dy;

        public Ball(int x, int y, int dx, int dy) {
            this.x = x;
            this.y = y;
            this.dx = dx;
            this.dy = dy;
        }
    }



}
+2

Source: https://habr.com/ru/post/1737778/


All Articles