Search code examples
javaswingjframetransparentkey-events

Getting mouse position in a transparent window


so I have a transparent window that draws a few lines and hud elements. I'm wondering if there's a way to get the position of the mouse within said window when I hit a hotkey set-up such as, say, ctrl-s or something and save the mouse x and y so I can repaint the frame with the updated variables.

My frame code is this:

JFrame frame = new JFrame();
frame.setUndecorated(true);
frame.add(new AimDriver());
frame.setBackground(new Color(0,0,0,0));
frame.setSize(resolutionX, resolutionY);
frame.setAlwaysOnTop(true);
frame.setVisible(true);

Where aimDriver has all the painting methods. Thanks for any help!


Solution

  • A KeyBinding provides several advantages over an KeyListener. Perhaps the most important advantages is that a KeyBinding does not suffer from issues of focus that can plague a KeyListener (See this question for a detailed explanation.)

    The below approach follows the KeyBinding Java Tutorial. First, create an AbstractAction that captures the location of the mouse within the window:

    AbstractAction action = new AbstractAction() {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            Point mLoc = MouseInfo.getPointerInfo().getLocation();
            Rectangle bounds = frame.getBounds();
    
            // Test to make sure the mouse is inside the window
            if(bounds.contains(mLoc)){
                Point winLoc = bounds.getLocation();
                mouseLoc = new Point(mLoc.x - winLoc.x, mLoc.y - winLoc.y);
            }
    
        }
    };
    

    Note: It's important to test that the window contains the mouse location; if you don't, the mouse location could easily contain a meaningless coordinate (e.g. (-20,199930), what does that even mean?).

    Now that you have the desired action, create the appropriate KeyBinding.

    // We add binding to the RootPane 
    JRootPane rootPane = frame.getRootPane();
    
    //Specify the KeyStroke and give the action a name
    KeyStroke KEY = KeyStroke.getKeyStroke("control S");
    String actionName = "captureMouseLoc";
    
    //map the keystroke to the actionName
    rootPane.getInputMap().put(KEY, actionName);
    
    //map the actionName to the action itself
    rootPane.getActionMap().put(actionName, action);