我看了一圈,似乎没有人能给我答案。我有一个 JPanel
,在它运行时我可以在其中添加/删除标签。问题是每次我向它添加新标签时,我都必须 revalidate()
它才能显示新标签。每次我 revalidate()
时,我都会遇到非常烦人的闪烁,并且我所有的标签都会在我的窗口顶部幻影一毫秒,然后返回到它们正在做的事情。我唯一一次调用 revalidate()
是在添加标签之后;我没有改变绘画方法或只是做了什么
public void paintComponent(Graphics page)
{
super.paintComponent(page);
}
这样我的页面就不会难看了。我真的需要一些帮助。我使用 JFrame
、Jlabel
和 Jpanel
游戏制作了一个小行星游戏;它工作得很好,但是这种闪烁和组件“重影快速重影到面板顶部”是令人难以忍受的,我知道这是 revalidate()
方法的事实。
最佳答案
使用标签(或通常的 GUI 组件)来表示快速动画、动态创建/移动的对象是不切实际的。就像用汽车从客厅开到厨房一样。
Swing 组件具有许多不错的功能,例如他们可以确定他们需要的空间,布局管理器可以使用它来自动将它们放置得很好。不幸的是,对于一款游戏,您既不需要所有好的东西,也不想支付与之相关的处理开销。 swings 的多平台功能使事情变得更加复杂,这些功能要求每个组件都有一个对等组件(对等组件负责将组件呈现为 Activity 外观)。
为解决此问题,您无需将单个游戏对象表示为 Swing 组件。相反,您使用单个 swing 组件(通常是 JPanel)作为 Canvas 来绘制您的游戏对象。您只需定期为该 JPanel 调用 repaint() (例如每秒 30 或 60 次)。当然,您将覆盖 JPanel 上的 paintComponent() 以使用您自己的代码绘制所有游戏对象。
编辑:概述您如何进行自己的渲染
您需要决定如何组织与游戏相关的对象。一个非常简单的框架可能看起来像这样(省略了 getters/setters):
public class GameObject {
public int x;
public int y;
public Image image;
}
在实践中,这个类会有额外的成员(比如控制对象移动方式的行为,可能还有一些动画状态/计数器)。它也可以是抽象的,每个可能的行为(如船舶、小行星和子弹)都有一个具体的子类。 GameObject 的所有实例都在某种集合中进行管理,我假设您使用的是列表。
当实现 paintComponent 时,归结为循环遍历列表并渲染每个对象的图像:
public void paintComponent(Graphics g) {
List<GameObject> list = ... // however you obtain it in your game
for (GameObject gobject : list) {
g.drawImage(gobject.image, gobject.x, gobject.y, (ImageObserver) null);
}
}
更复杂的游戏可能会命令游戏对象控制游戏对象如何相互重叠。但原则上它非常简单。
关于java - 重新验证 JPanel 时闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14909274/