I'm working on a project and I've read up as much as I can on double buffering in java. What I want to do is add a component or panel or something to my JFrame that contains the double buffered surface to draw to. I want to use hardware acceleration if possible, otherwise use regular software renderer. My code looks like this so far:
public class JFrameGame extends Game {
protected final JFrame frame;
protected final GamePanel panel;
protected Graphics2D g2;
public class GamePanel extends JPanel {
public GamePanel() {
super(true);
}
@Override
public void paintComponent(Graphics g) {
g2 = (Graphics2D)g;
g2.clearRect(0, 0, getWidth(), getHeight());
}
}
public JFrameGame() {
super();
gameLoop = new FixedGameLoop();
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new GamePanel();
panel.setIgnoreRepaint(true);
frame.add(panel);
panel.setVisible(true);
frame.setVisible(true);
}
@Override
protected void Draw() {
panel.repaint(); // aquire the graphics - can I acquire the graphics another way?
super.Draw(); // draw components
// draw stuff here
// is the buffer automatically swapped?
}
@Override
public void run() {
super.run();
}
}
I created an abstract game class and a game loop that calls Update and Draw. Now, if you see my comments, that's my main area of concern. Is there a way to get the graphics once instead of going through repaint and paintComponent and then assigning a variable every redraw? Also, is this hardware accelerated by default? If not what should I do to make it hardware accelerated?
If you want more control over when the window is updated and to take advantage of hardware page flipping (if available), you can use the BufferStrategy
class.
Your Draw
method would then look something like this:
@Override
protected void Draw() {
BufferStrategy bs = getBufferStrategy();
Graphics g = bs.getDrawGraphics(); // acquire the graphics
// draw stuff here
bs.show(); // swap buffers
}
The downside is that this approach does not mix well with event-driven rendering. You generally have to choose one or the other. Also getBufferStrategy
is implemented only in Canvas
and Window
making it incompatible with Swing components.
Tutorials can be found here, here and here.
Don't extend JPanel
. Extend JComponent
. It's virtually the same and has less interfering code. Also, you'd do the drawing code in paintComponent
only. If you need to manually refresh the component, you'd use component.redraw(
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With