Java:如何通过鼠标单击中断程序执行中途

标签 java swing events event-handling mouselistener

如何实现一个鼠标监听器(或其他方式,无关紧要)来处理程序任何部分的鼠标单击事件?最好在单击事件处理程序方法完成时返回到它离开的行。

我正在使用 Swing 。 “上下文”是一个不断更新的 GUI,但必须随时响应用户的鼠标点击,没有延迟。事实上,我确实有事件方面的经验,使用和覆盖它们的处理程序等,我想不是太深入,但到目前为止我所知道的已经足够了。

最佳答案

我无法理解你的第一段,所以如果我理解正确的话,我的答案适用于你的第二段。 ;)

Swing 遵循单线程模型。因此,您应该从 Event Dispatch Thread 更新 UI (美东时间)。该线程也负责将事件传递给您的代码,因此得名。如果您在循环中不断更新 UI,那么这将使 EDT 保持忙碌和阻塞。最终效果将是 UI 不响应用户事件。这是因为事件正在排队,EDT 可以挑选它们并在空闲时将它们传送到您的代码。

游戏通常会遇到这种场景。您可能已经注意到,游戏通常有一种固定的刷新率,称为 FPS(每秒帧数)。通常保持 60 FPS 就足够了。也就是说,您需要每秒绘制 UI 50 次,但现在看来您的渲染循环(更新 UI)正在连续运行。

您需要有单独的线程持续运行,负责绘制 UI。这应该绘制到缓冲区(Image)中。然后在要更新的 UI 元素上调用 repaint()。该 UI 元素的 paintComponent() 需要重写,以便它可以复制 Image 缓冲区中的图像并将其绘制在图形上下文上。

现在真正的技巧来了。调用 repaint() 的循环必须执行一些算术,以确保它不会超过每秒绘制 60 次,即循环 60 次。如果这样做,那么它必须调用 Thread.sleep(sleepTime) ,其中 sleepTime 是循环 60 次后每秒剩余的毫秒数。有时您的循环可能需要超过一秒才能完成 60 次迭代,那么不要只继续下一次迭代,而是调用 Thread.yield() 。这将使其他线程有机会使用 CPU,例如也许是你的 EDT。让事情变得更复杂的是,不要总是保持让步,因此可能需要添加一些逻辑来确保仅连续 x 次让步。最后一种情况如果有的话,应该是非常罕见的。这种情况说明系统负载过重。

请记住,repaint() 是线程安全的,允许从任何线程调用。它在 EDT 上安排 paint() 调用。因此,调用 repaint() 并不能保证绘制。因此,您可能需要尝试不同的 FPS 值以找到适合您的值。

顺便说一句,渲染到内存中Image的技巧在技术上称为双缓冲区。这使我们能够渲染漂亮流畅的动画。

进一步阅读:-

关于Java:如何通过鼠标单击中断程序执行中途,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9042720/

相关文章:

java - 访问匿名内部类中封闭范围的成员变量

java - 如何在屏幕周围放置 JButton?

c# - 如何安全地摆脱事件处理程序?

Javascript/jQuery : Why different result for event. 目标使用 <a> 标签对比。 console.log 中的其他元素,注意 $(this) 的 alert()

java - 获取 Protocol Buffer 中的字段描述符

java - 尽管查询不同,Sql2o仍然返回同一组数据

java - 需要帮助来实现从 Java 应用程序拖放到 native 文件系统

Java Swing : Caret-listener stops firing after JPopupMenu is shown

java - Google 服务 3.3.0 升级错误 - 多个项目变体匹配

angularjs - 用户刷新浏览器时 $stateChangeStart 不起作用