3

I'm using Java2D for a game I'm writing and haven't had any issues using it until I started integrating it with other swing components. My problem is when the first component I add to the JFrame is not the canvas I'm drawing to, I get a weird artifact that shows up when I mouse over the scroll bar for the textpane. It happens every time I execute the application. When I have the canvas first, there's no problem.

For some reason this appears to only occur on Windows when the default Java2D pipeline is in use (which happens to be sun.java2d.d3d=true), and the artifact occurs. When I set sun.java2d.opengl=true or sun.java2d.noddraw=false AND sun.java2d.d3d=false, then it does not occur.

I'm guessing this is some kind of bug with the Direct3D Java2D pipeline? I can easily work around it, but curious to know if anyone else has run into such an issue? I'm running the latest JDK7u7, but it happens with previous versions as well. I should note that if I minimize the window and restore it, the artifact goes away and never returns until I restart the application.

with artifact: bad

with no artifact (after adding the canvas first instead of the JLabel image): good

If someone has any further info on this I'd appreciate it. Thanks!

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Consty
  • 1,792
  • 1
  • 15
  • 14
  • 2
    Can you reproduce a simple working example? It could be an issue of heavy and light weight components, incorrect paint chain, threaded updates...would you like us to continue guessing?? – MadProgrammer Oct 12 '12 at 01:56
  • I believe you are correct, it probably does have to do with mixing the Canvas class with JFrame/JTextPane etc. The issue is from my research it doesn't appear like there is a lightweight equivalent to the Canvas class. That probably means I have to roll my own double buffering – Consty Oct 12 '12 at 02:59
  • `JComponent` jumps to mind, although `JPanel` is probably a better choice. They are both provide double buffering out of the box – MadProgrammer Oct 12 '12 at 03:02

1 Answers1

5

This is a well-know artifact from failing to honor the opacity property. Because "Swing programs should override paintComponent() instead of overriding paint()," be sure to invoke super.paintComponent() first in your implementation. There are related examples here and here.

Addendum: See also Mixing Heavyweight and Lightweight Components.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I don't override paint() or paintComponent() since I use the BufferStrategy to get the Graphics2D class to draw to within a dedicated thread. I do inherit from Canvas, but is this heavyweight? If so, is there a lightweight equivalent that works well with Swing? – Consty Oct 12 '12 at 02:54
  • `JPanel` is a good choice, as it enables the default `BufferStrategy`, but I think GL needs a `java.awt.Canvas`. Edited: More [here](http://stackoverflow.com/a/12447916/230513). – trashgod Oct 12 '12 at 03:01
  • 1
    Looks like switching to a JPanel and using the internal double buffering worked like a charm. I just had to switch my gameloop to call repaint() instead and place all my drawing code in paintComponent() and now I no longer get the artifact. It was definitely caused by mixing lightweight and heavyweight components. Thanks! – Consty Oct 12 '12 at 23:45