【问题标题】:Swing Timer stops calling actionPerformed() while the mouse is moving inside a JFrame当鼠标在 JFrame 内移动时,Swing Timer 停止调用 actionPerformed()
【发布时间】:2016-11-29 06:03:10
【问题描述】:

如果我在 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 对。

【问题讨论】:

  • 你在 Windows 或 macOS 上测试过吗?当我将 Kone XTD 移动到 JFrame 中时,计时器停止调用 actionPerformed()。当我将鼠标移出 JFrame 或使用触控板时,一切都很好。
  • 打电话给frame.requestFocus();对我没有影响:(
  • EDT 外部调用 Swing 组件可能会出现不可预知的行为。这里可能会也可能不会,但是使用SwingUtilities.invokeAndWait 在 EDT 上进行 Swing 调用(例如,main 方法中的所有代码都应该放在里面)
  • 感谢您的回复,但这并不能解决我的问题。
  • 谢谢。使用 TimerTask 是一个可行的解决方案,但是当我将动画 gif(JLabel 上的 ImageIcon)添加到我的 JFrame 时,也会出现我的问题。当我的鼠标移动时动画停止。有没有手动动画 gif 的解决方案?

标签: java swing timer mouse actionlistener


【解决方案1】:

当我将鼠标的轮询率从 1000Hz 降低到 500Hz 时,我解决了这个问题。现在一切都很完美。我认为问题在于 UI 线程在处理每秒 1000 次轮询时过度扩展,因此忙于处理 Timer

【讨论】:

    猜你喜欢
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多