2010-05-16 65 views
1

我在执行DoubleBuffer时遇到了一些麻烦。在你离开文本墙之前,你应该知道它有很多,以防万一你需要知道。我认为我遇到问题的实际地点是一种方法。Java中的DoubleBuffering

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

我不知道如果你知道它是否有什么区别,但下面是主要方法的代码。这只是一个显示其中的ChronosDisplay类的框架。我省略了不相关的代码“...”

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

回答

1

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

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

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

+0

感谢您指点我的大方向,camikr。但是,你能告诉我什么是美国东部时间?在Google上进行简单的搜索并不能提供相关结果。 – exodrifter 2010-05-16 03:57:14

+0

EDT是事件调度线程。请阅读Swing教程中有关“并发”的部分以获取更多信息:http://java.sun.com/docs/books/tutorial/uiswing/TOC.html – camickr 2010-05-16 05:37:41

+0

再次感谢,camickr! :D – exodrifter 2010-05-16 14:24:57

0

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

+0

对不起,改变构造方法为... 公共ChronosDisplay(字符串str) { MAPNAME = STR; setVisible(true); createBufferStrategy(2); new Thread(this).start(); } ...没有解决问题(我仍然得到相同的错误)。 – exodrifter 2010-05-16 02:40:04

+0

不要将可见与可显示相混淆 – finnw 2010-06-11 14:42:03

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); 
} 
+0

嗯,有趣。我必须尝试一下:) – exodrifter 2010-06-11 14:37:25