【问题标题】:DoubleBuffering in JavaJava中的双缓冲
【发布时间】:2011-02-20 00:07:54
【问题描述】:

在我的程序中实现 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

【问题讨论】:

    标签: java user-interface doublebuffered


    【解决方案1】:

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

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

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

    【讨论】:

    • 感谢您为我指明大方向,camikr。但是,你能告诉我EDT是什么吗?在 Google 上进行简单搜索并没有得到相关结果。
    • EDT 是事件调度线程。阅读 Swing 教程中关于“并发”的部分以获取更多信息:java.sun.com/docs/books/tutorial/uiswing/TOC.html
    • 对于主动渲染(您需要精确控制何时绘制组件),有时将Canvas 添加到 Swing 容器合适的。
    【解决方案2】:

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

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

    【讨论】:

    • 嗯,很有趣。有时间我得试试看:)
    【解决方案3】:

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

    【讨论】:

    • 抱歉,将构造方法更改为... public ChronosDisplay (String str) { mapName = str;设置可见(真);创建缓冲区策略(2);新线程(this).start(); } ...没有解决问题(我仍然得到同样的错误)。
    • 不要混淆可见和可显示
    猜你喜欢
    • 1970-01-01
    • 2011-08-20
    • 2012-03-22
    • 1970-01-01
    • 2011-01-05
    • 2013-08-07
    • 2012-07-25
    • 2023-04-09
    相关资源
    最近更新 更多