Swing Timer stops calling actionPerformed() while

2019-03-02 09:54发布

问题:

If I move my mouse inside a javax.swing.JFrame, the javax.swing.Timer stops calling the actionPerformed() method until the mouse stops moving. It only occurs when I move the cursor with my Rocket Kone XTD mouse. When I use my trackpad everything is fine.

How can I fix it? I'm using macOS Sierra.

Here's my code:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.Timer;

public class Mouse {
    public static void main(String[] args) {
        JFrame frame = new JFrame();

        frame.setSize(500, 500);
        frame.setVisible(true);

        Timer timer = new Timer(10, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("foo");
            }
        });

        timer.start();
    }
}

To get an idea what I'm talking about:

Code that gives more detail:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Mouse {
    public static void main(String[] args) {
        // Note: Swing/AWT GUIs should be started on the EDT!
        // If the problem displayed here, that is first change I'd make to code.
        final JFrame frame = new JFrame();

        frame.setSize(500, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        Timer timer = new Timer(10, new ActionListener() {

            long lastTime = 0;

            @Override
            public void actionPerformed(ActionEvent e) {
                long nowTime = System.currentTimeMillis();
                long difference = nowTime-lastTime;
                lastTime = nowTime;
                Rectangle r = frame.getBounds();
                Point p = MouseInfo.getPointerInfo().getLocation();
                System.out.println(String.format("%1s\t%2s", 
                        difference, r.contains(p)));
            }
        });

        timer.start();
    }
}

Output:

If the mouse is not moving, the output it looks like this: 11 true 13 true 13 true 10 true 12 true 13 true 12 true 13 true 10 true.

While the mouse is moving (fast) there is no output. When the mouse stops moving the output is: 2406 true (depending how long I moved my mouse).

If the mouse is moving slowly, the output looks like this: 17 true 5 true 8 true 16 true 4 true 11 true 16 true 44 true 11 true 28 true 48 true 77 true 11 true 7 true 15 true 8 true 9 true 12 true 24 true 13 true 4 true 12 true 32 true 13 true 8 true 8 true 13 true 10 true 15 true.

回答1:

I solved the problem as I reduced the polling-rate of my mouse from 1000Hz to 500Hz. Now everything works perfect. I think the problem was that the UI-Thread was overextended handling the 1000 polls per second so it was to busy to handle the Timer.