0

This is a little mouse hook application that I wrote a few years ago and I just was wondering why it makes my mouse lag whenever I run it.

I remember reading somewhere that I have to call some method to manually dispose of resources or something with the MouseListener. It will make my mouse lag whenever I drag any window around the screen, and this doesn't happen when it's not running. Any idea why? (I know I'm running a while loop on the EDT and my variable names for the 2 JLabels are J and C, sue me)

import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JLabel;


public class MouseLocation {

    Point p;
    int x,y;

    MouseLocation() throws AWTException {

    }

    public String printLocation(){
        p = MouseInfo.getPointerInfo().getLocation();
        x = p.x;
        y = p.y;
        String location = (x + " - " + y);

        return location;
    }

    public Color getMouseColor() throws AWTException{
        Robot r = new Robot();
        return r.getPixelColor(x, y);
    }



    public static void main(String[] args) throws AWTException {
        MouseLocation m = new MouseLocation();

        JFrame frame = new JFrame("Mouse Location Display");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(450,110);
        frame.setLayout(new FlowLayout());
        JLabel j = new JLabel();
        JLabel c = new JLabel();

        j.setFont (j.getFont ().deriveFont (24.0f));
        c.setForeground(Color.red);

        frame.add(j);
        frame.add(c);
        frame.setVisible(true);
        while (true){
            j.setText("Current Mouse Location: " + m.printLocation());

            c.setText(String.valueOf(m.getMouseColor()));
        }
    }
}
apangin
  • 92,924
  • 10
  • 193
  • 247
Preston Garno
  • 1,175
  • 10
  • 33

1 Answers1

3

You are requesting the mouse position at a very fast rate. Try adding a Thread.sleep(time) in your loop:

while (true){
    j.setText("Current Mouse Location: " + m.printLocation());
    c.setText(String.valueOf(m.getMouseColor()));

    // waiting a few milliseconds
    Thread.sleep(200);
}

Also, it's best practice to reuse objects to avoid reallocation. You could improve your method getMouseColor like this:

// Global var
Robot robot;

MouseLocation() throws AWTException {
    robot = new Robot();
}

public Color getMouseColor() {
    return robot.getPixelColor(x, y);
}

EDIT:

Following the suggestion by @cricket_007, use a timer to avoid using a Thread.sleep in the main thread (and inside a while-loop):

new Timer().schedule(new TimerTask() {

    @Override
    public void run() {
        j.setText("Current Mouse Location: " + m.printLocation());
        c.setText(String.valueOf(m.getMouseColor()));
    }
}, 0, 200); // 200 milliseconds
D.Kastier
  • 2,640
  • 3
  • 25
  • 40
  • I would suggest making that its own Thread, rather than sleeping the main Thread – OneCricketeer Mar 12 '16 at 13:54
  • @Zack thanks for the answer. I think it's the rate of the request + reallocation. The thread will really only make the windows close button respond a few milliseconds earlier since there's no other functionality in the application. – Preston Garno Mar 12 '16 at 14:16
  • You're welcome and right: in my tests the 'bottleneck' is the rate. You should use a thread if you will do some processing with the acquired value. – D.Kastier Mar 12 '16 at 14:22