当鼠标在 JFrame 内移动时,Swing Timer 停止调用 actionPerformed()

Swing Timer stops calling actionPerformed() while the mouse is moving inside a JFrame

如果我在 javax.swing.JFrame 内移动鼠标,javax.swing.Timer 会停止调用 actionPerformed() 方法,直到鼠标停止移动。它仅在我使用 Rocket Kone XTD 鼠标移动光标时发生。当我使用触控板时一切正常。

我该如何解决?我正在使用 macOS Sierra。

这是我的代码:

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();
    }
}

想知道我在说什么:

提供更多细节的代码:

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();
    }
}

输出:

如果鼠标不动,输出如下: 11 真 13 真 13 真 10 真 12 真 13 真 12 真 13 真 10 正确。

当鼠标移动(快速)时没有输出。当鼠标停止移动时,输出为:2406 true(取决于我移动鼠标的时间)。

如果鼠标移动缓慢,输出如下:17 true 5 真 8 真 16 真 4 真 11 真 16 真 44 真 11 真 28 真 48 真 77 真 11 真 7 真 15 真 8 真 9 真 12 真 24 真 13 真 4 真 12 真 32 真 13 真 8 真 8 真 13 真 10 真 15 正确。

我解决了这个问题,因为我将鼠标的轮询频率从 1000Hz 降低到 500Hz。现在一切正常。我认为问题在于 UI-Thread 过度扩展,每秒处理 1000 个轮询,因此它忙于处理 Timer.