2

I am creating and updating a BufferedImage on a background thread. The image is then drawn onto a JPanel by overriding the panels paint method as shown.

@Override
public void paint(Graphics g) {
    g.drawImage(image, 0, 0, null);
}

The background thread periodically updates the image then calls the panels invalidate method.

Will I run into any issues with this approach? Will the swing thread reading and the background thread updating the image cause any problems?

Thanks

Ben

mKorbel
  • 109,525
  • 20
  • 134
  • 319
benshort
  • 670
  • 8
  • 14
  • it depends, if you're drawing (via AWT thread) at the same time when you're updating the image, then you have problems. Thread synchronization. – Adrian Mar 01 '12 at 21:51
  • 1
    As an aside, "Swing programs should override `paintComponent()` instead of overriding `paint()`."—[Painting in AWT and Swing: The Paint Methods](http://java.sun.com/products/jfc/tsc/articles/painting/index.html#callbacks). – trashgod Mar 01 '12 at 23:11
  • 1
    1) In addition to what trashgod was mentioning, note that the `null` parameter passed as the last argument to `drawImage` is an `ImageObserver`. Since `JPanel implements ImageObserver`, it should be `g.drawImage(image, 0, 0, this);`. 2) Unless you are stretching the image to fill that panel, or adding other components on top, I'd use a `JLabel` to display it. 3) If stretching the image, but **not** overlaying components, render in a `JComponent`. – Andrew Thompson Mar 02 '12 at 06:40

1 Answers1

2

The two threads must synchronize access to the shared data. SwingWorker is the most reliable approach with which to periodically publish the BufferedImage; there's an example here using Double. You might also look at the example here, which relies on the (implicit) ordering afforded by he EventQueue and repaint(). In either case, the limiting factor is the timer frequency relative to the repaint time.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • What I ended up doing was creating a copy of the image in the background thread. The JPanel implements a callback interface which the background thread calls passing the copy. The JPanel then uses `SwingUtilities.invokeLater` to set the JPanel into a variable and call repaint on its self. – benshort Mar 05 '12 at 08:29