Java中的DoubleBuffering

时间:2010-05-16 02:09:08

标签: java user-interface doublebuffered

我在将DoubleBuffer实现到程序中时遇到了一些麻烦。在你从文本墙上晕倒之前,你应该知道它有很多,以防你需要知道。我觉得我遇到问题的实际地方是一种方法。

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

我不知道如果你知道它是否有任何区别,但以下是主方法的代码。这只是一个在其中显示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

3 个答案:

答案 0 :(得分:1)

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

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

应在EDT上创建所有Swing组件。阅读Swing教程,了解有关如何执行此操作的示例。

答案 1 :(得分: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);
}

答案 2 :(得分:0)

通常关于双缓冲的错误意味着目标尚未可见。在窗口设置为可见并创建双缓冲区策略后尝试将线程开始推送到