我正在处理的程序包含一个名为GameForm
的类,它扩展了JFrame
。此表单将包含地图(只是一系列矩形),以及地图上的某些对象。
但是,我无法使用单个paintComponent(Graphics g)
函数绘制所有这些对象,因为并非游戏中的所有对象都必须同时绘制。例如,drawMap()
函数仅在表单首次加载时调用,而所有其他绘图函数将在每次转弯后调用。
但是,根据我的阅读(如果我错了请纠正我),类中只允许一个paintComponent
函数,其他函数不能使用它的Graphics2D
对象。
是否有任何关于如何实施这一点的想法?
答案 0 :(得分:1)
对Swing / GUI编程不熟悉的人通常认为JFrames
就像绘图表面或纸张。但是,你必须习惯这种情况并非如此。
首先,GUI程序有某种EDT(Event Dispatch Thread)。此线程是所有GUI操作发生的位置。此处更新GUI并响应用户输入。这是必要的,因为用户交互和GUI的程序化更改需要很好地同步。
回到主题,JFrame
基本上只是一个注册到系统的矩形,作为你的“绘图表面”。 要求绘制它,而不仅仅是在它上面绘画。
这就是paintComponent(Graphics)
的好处。显然,你不想一直画画。它的工作原理如下:
paintComponent()
的图片用于重绘您的框架(快速)如果你想为你的框架设置动画,你必须像这样工作:
repaint()
)paintComponent()
并重新绘制您的内容请注意延迟很重要,因为所有这些都发生在神圣的EDT上。 EDT处理所有事情并需要“呼吸”,以便用户在您制作动画时可以做一些事情。
总而言之,您所学到的是:
paintComponent()
时,绘制到表面repaint()
- > paintComponent()
将被称为最后要考虑的事项:不要使用JFrame
直接绘制。
而不是那样,向框架添加JPanel
并覆盖其paintComponent()
方法。
答案 1 :(得分:0)
一般来说,您希望实现的目标可以通过几种方式完成。它与所谓的 sprites (http://en.wikipedia.org/wiki/Sprite_%28computer_graphics%29)和图像缓冲(http://en.wikipedia.org/wiki/Multiple_buffering)严格相关。最简单的方法是:
a)paintComponent()
JPanel
JFrame
添加到您的JFrame
,通过处理所有输入数据/用户事件/机器状态生成生成的图像,
JFrame
上 - paint()
的状态将仅在绘制事件(paintComponents()
,JFrame
上更新等,如果地图发生变化而没有直接repaint()
交互(调整窗口大小,用其他框架覆盖等),例如通过调用getGraphics()
等,你必须手动强制失效。
c)您可以通过调用Graphics2D
(http://docs.oracle.com/javase/7/docs/api/javax/swing/JFrame.html#getGraphics%28%29)获取绘图上下文,然后在需要时使用返回的对象(可能已转换为JPanel
)作为您的画布。请注意,就效率而言,这实际上是最差解决方案。
他们是唯一可能的 - 我曾经一次使用OpenGL / JOGL来满足我的大部分2D渲染需求,因为它允许疯狂渲染速度以及3D的所有利润图形[插值,缩放,旋转,alpha混合,透视,几何变形,着色等],只需很少的功能开销。
另外,请注意,通常建议使用专用画布组件(例如JFrame
)而不是全局JFrame
- 它连接到 - 称轻量级与重量级组件差异以及其他OOP / Swing / AWT / EDT问题;它还允许隐藏地图,并通过一个简单的JPanel #setVisible(false)调用将{{1}}重新用于其他内容。
有关详细信息,请参阅java what is heavier: Canvas or paintComponent()?。