问题
I'm having some trouble implementing DoubleBuffer into my program. Before you faint from the wall of text, you should know that a lot of it is there just in case you need to know. The actual place where I think I'm having problems is in one method.
I've recently looked up a tutorial on the gpwiki about double buffering, and decided to try and implement the code they had into the code I have that I'm trying to implement doublebuffer in. I get the following error: "java.lang.IllegalStateException: Component must have a valid peer".
I don't know if it makes any difference if you know it or not, but the following is the code with the main method. This is just a Frame that displays the ChronosDisplay class inside it. I omitted irrelevant code with "..."
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");
}
}
Here is the code where I think the problem resides (I think the problem is in the paint() method). This class is displayed in the CDM class
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) ...
}
}
If you're curious (I doubt it matters), the draw() method in the Tile0 class is:
public void draw( Graphics window )
{
window.drawImage(img,getX(),getY(),50,50,null);
}
Any pointers, tips, or solutions are greatly appreciated. Thanks for your time! :D
回答1:
Swing is double buffered by default so you don't need to implement it yourself.
You should not be using the Canvas class in a Swing application. That is don't mix AWT and Swing components.
All Swing components should be created on the EDT. Read the Swing tutorial for examples on on how to do this.
回答2:
Override addNotify()
and create the BufferStrategy
from there:
public ChronosDisplay (String str)
{
mapName = str;
new Thread(this).start();
// Note: no createBufferStrategy() or setVisible()
}
public void addNotify() {
super.addNotify();
createBufferStrategy(2);
}
回答3:
Usually that error in regards to double buffering means the target isn't visible yet. Try pushing the thread start to after the window is set visible and the double buffer strategy is created
来源:https://stackoverflow.com/questions/2842366/doublebuffering-in-java