Issues with drawing layers of Graphics G and Graphics G2D

Hello!
I’m working on my first real game. It is tile-based, and I am only using a library to play mp3’s at the moment.

I added a lighting effect to my game with G2D RadialGradientPaint and setComposite, and I am having troubles drawing anything on top of that layer in regular graphics g.

This class draws a light circle around the player which gets darker towards the edges and allows me to adjust the radius, simulating night/day vision distance somewhat.

public void render(Graphics g) {  
        x = TileGame.getPlayer().getX() + 16;
        y = TileGame.getPlayer().getY() + 16;
        
        Graphics2D g2d = (Graphics2D) g;
        java.awt.geom.Point2D center = new java.awt.geom.Point2D.Float((float)x, (float)y);
        
        float[] dist = {0.0f, 1.0f};
        Color[] colors = {new Color(0.0f, 0.0f, 0.0f, 0.0f), Color.BLACK};
        RadialGradientPaint p = new RadialGradientPaint(center, currentRadius, dist, colors);
        g2d.setPaint(p);
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, .6f));
        
        g2d.fillRect(64, 64, 640, 640);
       
        g2d.dispose();
    }

In my main game loop, I have multiple things being rendered in a specific order.


                .  .  .  .
                levelManager.render(g);               
                ui.render(g);
                crops.render(g);
                player.render(g);                
                light.render(g);

My issue is this: In the above snippet, I want to draw UI.render() after the light.render() effect (which uses g2d). For some reason, if I put them in this order:


                .  .  .  .
                levelManager.render(g);  
                crops.render(g);
                player.render(g);                
                light.render(g);
                ui.render(g);

None of the UI gets rendered, even ones which weren’t within the original g2d.fillRect(64, 64, 640, 640) area. It seems like I need to cast my g2d back into g? Not sure how to solve this, I would appreciate some assistance.

Tip:

This should be how rendering methods work for objects to make sure you are not changing the graphics object passed in.


public void render(Graphics g)
{
Graphics g2d = g.createGraphics(); //cast this to g2d
.
.
.
//render stuff

g2d.dispose();

}

What ever you call on graphics objects carry over to anything else using them like objects should. So if you say set a certain color or alpha composite then the next call to the object will have those applied. To keep from always having to track that, simply never change the "base" graphics object and just create a new one from it when you render. 

I’m trying what you suggested, but getting an error.

g.createGraphics(); :: cannot find symbol :: method createGraphics :: location variable g of type Graphics

What you’re saying is that when I do “(graphics2D) g” cast, it actually changes the original g?

Ok, so I found that my graphics g has a “create()” method, which returns a copy of the current graphics context.


public void render(Graphics g) {
        
        Graphics preG2D = g.create();
        Graphics2D g2d = (Graphics2D) preG2D;

This has fixed my original problem, at least I think so. What do you think?

Yup but you can make that one step like so


Graphics2D g2d = (Graphics2D)g.create();

draw stuff


g2d.dispose();