在Java中,鼠标按下时*连续*触发哪个事件?

5

我想知道Java中是否存在一种事件,在鼠标按钮被按下(按住)时持续不断地触发,即使鼠标没有移动。我在典型的MouseListeners中找不到它:

  • 只有在用户移动鼠标并按住按钮时才会触发MouseDragged
  • 只有当按钮已经被按下时才会触发MousePressed

就是这些内容。有什么办法可以创建这样的事件吗?

谢谢!

jy


你确定你不是想说重复吗?如果有无限数量的事件,你会如何应对? - robertc
我在考虑给另一个线程分配任务并等待。当线程返回时,如果按钮仍然处于打开状态,则再次执行该任务。 - Jean-Yves
5个回答

8
如果您需要在鼠标按下时执行某些操作,只需在检测到 mousePressed 事件时开始,并持续进行直到检测到 mouseReleased 事件。这样,您就不需要持续触发事件了。例如:
public void mousePressed(MouseEvent e) {
    someCondition = true;
    while(someCondition) {
        //do something
    }
}

public void mouseReleased(MouseEvent e) {
    someCondition = false;
}

编辑: 正如其他人所说,必须将代码与事件线程分离,否则对mouseReleased的调用会被阻塞,从而防止循环结束。


你可能想要从事件处理线程中解耦。 - Alex Feinman

8
这个事件没有提供给MouseListener的明显原因是它会让你收到大量事件,导致一切变得非常缓慢。你是否想每秒、每毫秒或者更频繁地接收这个事件?如果需要,你需要自己处理。
为了控制这个过程,你当然需要使用mousePressed和mouseReleased来确定当前按钮是否被按下。然后你需要运行某种类型的循环,生成相应的事件。
你可能还想通过轮询来工作,即扩展MouseListener类以便它可以告诉你一个按钮是否仍然被按下,并且在你需要这些事件的任何地方,你都可以主动轮询该按钮。这取决于你想要如何使用这些事件,哪种方法更适合。

5

James Goodwin的代码无法正常工作。mousePressed和mouseReleased都是从GUI线程触发的,因此在mousePressed中阻塞将导致mouseReleased永远不会被触发,这意味着循环将一直继续。

如果您已经有一个用于处理的单独线程,请使用mousePressed指示该线程应开始事件,并使用mouseReleased停止。

如果您没有单独的线程并且不想麻烦,Timer可能是最简单的方法。 Timer上的javadoc

具体来说,您应该创建一个TimerTask,多次执行所需的操作,并使用Timer.schedule将其排队:

Timer timer = new Timer();
TimerTask task = new MyTimerTask();

private class MyTimerTask extends TimerTask {
    public void run() {
        // your code here
    }
}

public void mousePressed(MouseEvent e) {
    timer.scheduleAtFixedRate(task, 0, 1000); // Time is in milliseconds
    // The second parameter is delay before the first run
    // The third is how often to run it
}

public void mouseReleased(MouseEvent e) {
    task.cancel();
    // Will not stop execution of task.run() if it is midway
    // But will guarantee that after this call it runs no more than one more time
}

我相信这是最简单的方法,因为它不涉及线程间通信的麻烦。

哦,正如Peter所说,您需要添加代码来处理用户在应用程序上按下鼠标并在其他地方松开鼠标的情况。


感谢您指出代码无法按预期工作,我只是提供了一个粗略的示例代码,并没有测试它是否实际可行。 - James Goodwin
这经过一些修改,完美地解决了我的问题。谢谢! - Fengson

1

没有这样的事件

您可以通过在mousedown方法中启动计时器并在mouserelease中结束相同的计时器来创建自己的事件

您还需要一些故障保护措施,以确保当您在mousedown上移动到另一个组件甚至移动到其他帧或非Java GUI部分时计时器停止


0

我认为你会发现答案是否定的,没有这样的事件。不仅对于Java,而是对于任何GUI框架都是如此。它除了占用事件队列之外没有任何作用。

您需要通过捕获鼠标按下事件,然后设置一个计时器以在规律的时间间隔内触发事件,直到鼠标抬起事件来创建自己的事件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接