Overlaying JME Canvas with Swing Graphics Panel

Hi,

I’m working on some tools and I’m trying to create a GUI with a native look and feel using Swing.

Most of this stuff (menus, toolbars, etc.) works fine, but now I want to overlay the JME Canvas with a JPanel for a paintComponent() implementation, so I can use Graphics2D draw commands on it.

Here is some initialization code:

// Render Panel
viewportPanel = new JPanel();
viewportPanel.setBorder( BorderFactory.createBevelBorder( BevelBorder.LOWERED ) );
viewportPanel.setLayout( new BorderLayout() );
window.add( viewportPanel );

JLayeredPane renderPanel = new JLayeredPane();
viewportPanel.add( renderPanel, BorderLayout.CENTER );
		
renderPanel.add( jmeCanvas, new Integer( 0 ) );
jmeCanvas.setBounds( 0, 0, 400, 400 );
		
GraphicsPanel gp = new GraphicsPanel();
gp.setDoubleBuffered( true );
gp.setBackground( new Color( 0, 0, 0, 0 ) );
gp.setOpaque( true );
renderPanel.add( gp, new Integer( 1 ) );
gp.setBounds( 0, 0, 200, 200 );

At this point I’m setting the components bounds manually to avoid any layout troubles.

Here is the super simple GraphicsPanel implementation:

public static class GraphicsPanel extends JPanel
{		
	@Override
	public void paintComponent( Graphics gfx )
	{
		super.paintComponent( gfx );

		Graphics2D g2d = ( Graphics2D )gfx;

		g2d.setColor( Color.RED );
		g2d.drawLine( 0, 0, 200, 200 );
	}
}

But unfortunatly it looks like this:

It seems like although I’m setting the background color to transparent (zero alpha as suggested by some stackoverflow thread) the graphics panel does not clear its background pixels and overdraws the JME canvas!

Could this be because JME’s rendering is done using hardware accelerated OpenGL where as Graphics2D is software drawing?

I already tried drawing graphics to a BufferedImage and use that for a texture overlay on the gui node but that has a very slow performance (and gets worse as the render panel is becoming larger).

I believe that the JPanel needs to be set to this.setOpaque( false ) ; not true. I personally have not attempted to render a JPanel on top of a jme3 canvas. Why do you want to use Graphics2D? JME3 has lots of ways to draw things like lines across the screen.

You might want to check other resources, such as this one: http://java-demos.blogspot.com/2013/09/creating-transparent-jpanel-in-swing.html
Stackoverflow, although full of information, is not always the best place for accurate info (still a good place to check though, I go there all the time :wink: )

Thanks for the reply!

I have already tried setOpaque( false ) but that did not help. Although the docs promise that the panel should not draw background pixels when set to false, it still does and looks the same as the screenshot above :frowning:

For some tools I want to be able to use graphics 2D stuff like drawing arcs, curves, polylines, round rectangles, dashed lines, etc.
All this would not be impossible to do using JME’s hardware rendering but I thought it would be less effort to just use what’s already there in Swing.

Did some more testing. Overlaying two graphics panels on top of each other works with either setOpaque( false ) or a background color with zero alpha.

The problem seems to be JME’s Canvas component that for some reason doesn’t let other components paint transparently over it.

Update:
Also if I change the background color of the viewport panel (viewport panel > layered render panel > JME Canvas + graphics panel) then that color is also rendered through to the graphics panel.

Screenshot:

I wonder if this has something to do with JME rendering in its own thread or something…

This probably has something to do with lwjgl. I would look and see what you can find on painting onto of a lwjgl canvas. JME3 uses LWJGL for the opengl library, and I do not think it does anything special with the lwjgl canvas other than wrap some helper functions around it. You can see that JME3 just creates the lwjgl display on the canvas here: jmonkeyengine/LwjglCanvas.java at f60ff58ef04aeb36f3addda7958d3d7f8942551e · jMonkeyEngine/jmonkeyengine · GitHub

The canvas itself is just a simple java.awt.Canvas, JME3 does not have a special canvas.

Can I just say that you have discovered that what you thought was easy is in fact not, and it won’t be your only problem either. In fact performance aside you will have threading and picking issues to come after that.

If you want to use a game engine you’re going to have to put your knowledge of applications aside and use game engine solutions. Drawing primitive shapes and arcs are pretty standard math daily workloads for game developers. There aren’t really any shortcuts to learning how these thing work in a game engine environment.

I would advise that you “go with the grain” on this one.

2 Likes

I have to say, I agree with @jayfella. This will only cause more and more problems as you progress on this project.

Okay guys, I’m finally convinced :sweat_smile:

I was hoping I was just missing some configuration parameter on some of the components and it has become obvious that it’s just too much of a hassle (although I already had something similar working with a second render target).

I will now go back to using my own gui node rendering procedures…