java - 重新验证 JPanel 时闪烁

标签 java swing jframe jpanel jlabel

我看了一圈,似乎没有人能给我答案。我有一个 JPanel,在它运行时我可以在其中添加/删除标签。问题是每次我向它添加新标签时,我都必须 revalidate() 它才能显示新标签。每次我 revalidate() 时,我都会遇到非常烦人的闪烁,并且我所有的标签都会在我的窗口顶部幻影一毫秒,然后返回到它们正在做的事情。我唯一一次调用 revalidate() 是在添加标签之后;我没有改变绘画方法或只是做了什么

public void paintComponent(Graphics page)
{
    super.paintComponent(page);
}

这样我的页面就不会难看了。我真的需要一些帮助。我使用 JFrameJlabelJpanel 游戏制作了一个小行星游戏;它工作得很好,但是这种闪烁和组件“重影快速重影到面板顶部”是令人难以忍受的,我知道这是 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/

相关文章:

java - Lombok 搞砸了 - IntelliJ IDEA

Java/JNI - 在 JNI_OnLoad 中查找类时出现 UnsatisfiedLinkError

java - 如何在Java中获取鼠标离开组件的通知

java - 永久更改 JComboBox 所选项目的颜色

java - 如何确保游戏在其他计算机上运行速度不会更快?

java - 在Java中实例化大量子类的最有效方法?

java - 为什么 EventDispatchThread 排在第一位?

java - JLabel图像图标: stop auto centering in the frame

java - java中如何将一个ComboBox中所选项目的相关数据获取到另一个ComboBox

Java 编码器。使用标签值作为属性值