如何实现在程序的任何部分处理鼠标点击事件的mouselistener(或其他方式,无关紧要)?最好在click事件处理程序方法完成时返回到它停止的行。
我正在使用摇摆。 “上下文”是一个不断更新的GUI,但必须随时响应用户的鼠标点击而没有延迟。事实上,我确实有过处理事件的经验,使用和覆盖他们的处理程序等等,我认为并不是太深入,但到目前为止,我所知道的已经足够了。
答案 0 :(得分:1)
你看过SwingWorker了吗?它是一个简单的框架,允许您在后台运行计算并定期发布GUI线程的更新。
答案 1 :(得分:1)
我无法理解你的第一段,所以如果我理解正确,我的答案就是第二段。 ;)
Swing遵循单线程模型。因此,您应该从Event Dispatch Thread(EDT)更新UI。该线程负责将事件传递给您的代码,因此也就是名称。如果您在循环中不断更新UI,那么这将使EDT忙碌并被阻止。最终效果将是不响应用户事件的UI。这是因为事件正在排队,EDT可以选择它们并在它们空闲时将它们传递给你的代码。
游戏通常会遇到这种情况。您可能已经注意到游戏通常具有一个固定的刷新率,他们称之为FPS(每秒帧数)。通常保持60 FPS就足够了。也就是说,您需要每秒绘制50次UI,但是现在看来您的渲染循环(更新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
的技巧在技术上称为双缓冲区。这使我们能够渲染漂亮流畅的动画。
进一步阅读: -