1

我在我的程序中实现 DoubleBuffer 时遇到了一些麻烦。在您从文字墙中晕倒之前,您应该知道其中有很多内容以防万一您需要知道。我认为我遇到问题的实际地方是一种方法。

我最近在 gpwiki 上查找了关于双缓冲的教程,并决定尝试将他们拥有的代码实现到我正在尝试实现双缓冲的代码中。我收到以下错误:“java.lang .IllegalStateException:组件必须有一个有效的对等体”。

不知道你知不知道有没有区别,但是下面是main方法的代码。这只是一个在其中显示 ChronosDisplay 类的 Frame。我用“...”省略了不相关的代码

public class CDM extends JFrame
{
    public CDM(String str)
    {
        super("CD:M - "+str);
        try
        {
            ...
            ChronosDisplay theGame = new ChronosDisplay(str);
            ((Component)theGame).setFocusable(true);
            add(theGame);
        }
        catch(Exception e)
        {
            System.out.println("CDM ERROR: " +e);
        }
    }
    public static void main( String args[] )
    {
        CDM run = new CDM("DP_Mini");
    }
}

这是我认为问题所在的代码(我认为问题出在 paint() 方法中)。该类在CDM类中显示

public class ChronosDisplay extends Canvas implements  Runnable
{
    String mapName;
    public ChronosDisplay (String str)
    {
        mapName = str;
        new Thread(this).start();
        setVisible(true);
        createBufferStrategy(2);
    }
    public void paint( Graphics window )
    {
        BufferStrategy b = getBufferStrategy();
        Graphics g = null; 
        window.setColor(Color.white);
        try
        {
             g = b.getDrawGraphics();
            paintMap(g);
            paintUnits(g);
            paintBullets(g);
        }
        finally
        { g.dispose(); }
        b.show();
        Toolkit.getDefaultToolkit().sync(); 
    }
    public void paintMap( Graphics window )
    {
        TowerMap m = new TowerMap();
        try
        {
            m = new TowerMap(mapName);
            for(int x=0; x<m.getRows()*50; x+=50)
            {
                for(int y = 0; y<m.getCols()*50; y+=50)
                    {
                        int tileType = m.getLocation(x/50,y/50);
                        Image img;
                        if(tileType == 0)
                        {
                            Tile0 t = new Tile0(x,y);
                            t.draw(window);
                        }
                        ...// More similar if statements for other integers
            }
            catch(Exception e) ...
    }
    ...// Additional methods not shown here
    public void run()
    {
        try
        {
            while(true)
            {
                Thread.currentThread().sleep(20);
                repaint();
            }
        }
        catch(Exception e) ...
    }
}

如果你好奇(我怀疑这很重要),Tile0 类中的 draw() 方法是:

public void draw( Graphics window )
{
    window.drawImage(img,getX(),getY(),50,50,null);
}

非常感谢任何指针、提示或解决方案。谢谢你的时间!:D

4

3 回答 3

1

覆盖addNotify()BufferStrategy从那里创建:

public ChronosDisplay (String str)
{
    mapName = str;
    new Thread(this).start();
    // Note: no createBufferStrategy() or setVisible()
}

public void addNotify() {
    super.addNotify();
    createBufferStrategy(2);
}
于 2010-06-11T13:51:45.427 回答
1

Swing 默认是双缓冲的,所以你不需要自己实现。

您不应该在 Swing 应用程序中使用 Canvas 类。那就是不要混合 AWT 和 Swing 组件。

所有 Swing 组件都应在 EDT 上创建。阅读 Swing 教程以获取有关如何执行此操作的示例。

于 2010-05-16T03:27:21.377 回答
0

通常,关于双缓冲的错误意味着目标还不可见。尝试在窗口设置为可见并创建双缓冲策略后将线程启动

于 2010-05-16T02:32:54.143 回答