我正在尝试编写代码以显示使用AWT和scala在窗口中四处移动的黑眼圈。我成功在想要的地方绘制了圆圈,但是图像被冻结了。
我正在扩展Frame的Display类的run()方法内使用一个简单的游戏循环:
final class Display(
val canvas: Canvas,
val updater : Updater
) extends Frame with Runnable {
this.add(canvas)
override def run() ={
setSize(canvas.size())
setVisible(true)
var updateTime = System.currentTimeMillis()
while(true) {
val frameStart = System.currentTimeMillis()
val frameEnd = frameStart + MILLIS_PER_FRAME
repaint()
canvas.paint(getGraphics())
while(updateTime < System.currentTimeMillis()) {
updater.update(MILLIS_PER_UPDATE, keyboard)
updateTime += MILLIS_PER_UPDATE
}
while(System.currentTimeMillis() < frameEnd) Thread.sleep(1)
}
setVisible(false)
}
我打电话给
repaint()
canvas.paint(getGraphics())
认为它将调用 canvas 的paint()方法在Frame上再次绘制图像。但这显然不是它的工作原理……
我相信画布的 paint(g:Graphics)方法可以正常工作,并且我通过println()进行了验证-调试了圆圈应该在运动。
请要求提供任何可以帮助您回答的代码,并感谢您的回答。
答案 0 :(得分:0)
repaint()
计划组件进行重新绘制,但是此操作尚未执行,必须在UI线程上执行。
基本上每个UI应用程序都有一个单独的专用线程,该线程计算应如何重画事物,然后重画事物。
该线程调用了您的run
操作,因此该线程也正在执行while(true)
。意思是,它永远不会离开run
,也永远不会到达负责重绘的代码段。
解决方案是根本不计算UI组件内部的任何逻辑:
您所做的是一个常见错误,您可以阅读更多有关搜索短语的信息,例如“为什么不阻止UI线程”,“为什么单独的UI线程”等。这是导致UI无响应(单击某些内容,然后所有内容都会冻结一会儿),在while(true)
之类的情况下,它会无限期阻止用户界面。恐怕在JVM引入其他一些具有延续性的本地方法之前,唯一推荐的方法是使用多个线程。