Even after using Java Swing for over a year, it still seems like magic to me. How do I correctly use a BufferStrategy, in particular, the method createBufferSrategy()
?
I would like to have a JFrame and a Canvas that gets added to it and then painted. I would also like to be able to resize (setSize()
) the Canvas. Every time I resize the Canvas it seems my BufferStrategy
gets trashed or rather, turns useless, since using show()
on the BufferStrategy
does not actually do anything. Also, createBufferStrategy()
has a weird non-deterministic behaviour and I don't know how to synchronize it correctly.
Here's what I mean:
public class MyFrame extends JFrame {
MyCanvas canvas;
int i = 0;
public MyFrame() {
setUndecorated(false);
setVisible(true);
setSize(1100, 800);
setLocation(100, 100);
setDefaultCloseOperation(EXIT_ON_CLOSE);
canvas = new MyCanvas();
add(canvas);
canvas.makeBufferStrat();
}
@Override
public void repaint() {
super.repaint();
canvas.repaint();
//the bigger threshold's value, the more likely it is that the BufferStrategy works correctly
int threshold = 2;
if (i < threshold) {
i++;
canvas.makeBufferStrat();
}
}
}
MyCanvas
has a method makeBufferStrat()
and repaint()
:
public class MyCanvas extends Canvas {
BufferStrategy bufferStrat;
Graphics2D g;
public MyCanvas() {
setSize(800, 600);
setVisible(true);
}
public void makeBufferStrat() {
createBufferStrategy(2);
//I'm not even sure whether I need to dispose() those two.
if (g != null) {
g.dispose();
}
if (bufferStrat != null) {
bufferStrat.dispose();
}
bufferStrat = getBufferStrategy();
g = (Graphics2D) (bufferStrat.getDrawGraphics());
g.setColor(Color.BLUE);
}
@Override
public void repaint() {
g.fillRect(0, 0, 100, 100);
bufferStrat.show();
}
}
I simply call MyFrame
's repaint()
method from a while(true) loop in the main method.
When threshold
is small (i.e. 2), bufferStrat.show()
in about 70% of all cases doesn't do anything - the JFrame just remains gray upon starting the program. The remaining 30% it paints the rectangle how it's supposed to. If I do threshold = 200;
, the painting succeeds close to 100% of the time I execute the program. Javadoc says that createBufferStrategy()
may take a while, so I assume that's the issue here. However, how do I synchronize and use it properly? Clearly, I'm doing something wrong here. I can't imagine that's how it's supposed to be used.
Does anyone have a minimal working example?