Java动画冻结

Java动画冻结,java,animation,jframe,jpanel,refresh,Java,Animation,Jframe,Jpanel,Refresh,我试图用Java编写一个简单的2d动画引擎,用于可视化以后的编程项目。但是,我的窗口刷新有问题。运行时,框架有时会显示空白面板,而不是所需的图像。这从一次几帧开始,间隔明显是随机的,随着程序继续运行,情况会恶化,直到实际图像偶尔闪烁进入视野。处理每个帧的代码都会运行,但帧中实际上没有显示任何内容。我相信问题可能更多地来自我的电脑,而不是我的代码(当然不是来自糟糕的规格),但我不确定。非常感谢你的帮助 三节课。代码如下: package animator; import java.awt.*;

我试图用Java编写一个简单的2d动画引擎,用于可视化以后的编程项目。但是,我的窗口刷新有问题。运行时,框架有时会显示空白面板,而不是所需的图像。这从一次几帧开始,间隔明显是随机的,随着程序继续运行,情况会恶化,直到实际图像偶尔闪烁进入视野。处理每个帧的代码都会运行,但帧中实际上没有显示任何内容。我相信问题可能更多地来自我的电脑,而不是我的代码(当然不是来自糟糕的规格),但我不确定。非常感谢你的帮助

三节课。代码如下:

package animator;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.AudioClip;

public class APanel extends JPanel
{

    public APanel(int l, int h){

        setPreferredSize(new Dimension(l,h));
        setLocation(80, 80);
        setVisible(true);
        setFocusable(true);     

    }

    public Graphics renderFrame(Graphics g){

        return g;

    }   

    public void paintComponent(Graphics g) {

        requestFocusInWindow();
        renderFrame(g);

    }

}



您的代码中有一些严重错误,可能是您的问题的原因或因素

  • j.setSize(a.getPreferredSize())
    是不相关的,只需使用
    JFrame#pack
    ,就可以得到更好的结果,因为它考虑了框架装饰
  • j.setSize(j.getComponent(0.getPreferredSize())使用
    JFrame#setresizeable
    并将其传递给
    false
  • 永远不要做
    j.getComponent(0).paint(j.getComponent(0.getGraphics())这个!您不负责Swing中组件的绘制,这是由
    repaitmanager
    决定的。只需调用
    j.repaint()
  • super(屏幕X,屏幕Y)
    …只需覆盖
    getPreferredSize
    方法并返回所需的大小
  • setLocation(80,80)无关,因为组件受布局管理器控制
  • setVisible(true)(在
    APanel
    内部)…Swing组件在默认情况下已可见,但windows和
    JInternalFrame
    s除外
最后

public void paintComponent(Graphics g) {
    requestFocusInWindow();
    renderFrame(g);
}
此方法永远不需要公开,您永远不希望有人能够调用它,这将打破绘制链,并可能对组件正确绘制自身的能力产生严重影响

在执行任何自定义绘制之前,必须调用
super.paintComponent
,否则最终可能会出现各种各样精彩的绘制工件和问题

切勿在
paint
方法中修改组件的状态,因为调用
requestFocusInWindow()“可能”不会立即出现问题在您的
油漆组件中
可能会产生您不知道的副作用

相反,它应该看起来更像

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    renderFrame(g);
}

永远不要做
j.getComponent(0).paint(j.getComponent(0.getGraphics())尝试在屏幕上绘制时!相反,只需对要更新的组件调用
repaint
。我已经实现了您的改进(谢谢!),问题在Windows上得到了解决——这是因为使用了paint()而不是repaint()。但是,我喜欢在Linux上工作,在Linux中动画速度会减慢,除非鼠标在动画窗口上移动或窗口正在移动。冻结显示渲染的最后一帧,而不是空白帧。我非常感谢任何关于修复此问题的建议。如果相关的话,我使用薄荷和肉桂作为我的桌面管理器。
public void paintComponent(Graphics g) {
    requestFocusInWindow();
    renderFrame(g);
}
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    renderFrame(g);
}