Need help to structure my "laggy" graphic interface SWING

Hello everybody,

first time posting on this forum, so please be nice :D.

I am programming a 2D tiles gamebut i have some probelms of lags. Ok, my computer is quite old, and the game works perfectly fine on gamer computer, but i amsure i have a problem in my interface architecture.

I tried to improve it several time and as far as i am, my architecture is the one below :

JFrame <- JLayeredPane <- JPanel

I use the JFrame to display the whole game. It implements a double buffering hardware based on a JLayeredPane.getGraphics()…

I use the JLayeredPaneto organize all my interface : show or hide the character inventory, craft interface, overview map, etc.

JPanel are used to paint all the interface components such as the global view, the charcater inventory, overview map, etc.
Each JPanel implements a software double buffering to update their image. They are also implementing the museListener for all the player actions.

Despite all that buffers, it is still laggy and not fluent.So i am sure there is a problem coming from the way i structured everything (for example, i guess the JLayredPane.getGraphics is not very fine because it use the EDT… but i don’t know any other way to do it.)

Tkank’s for you’r help and advices.

Please also excuse my english… i am doing my best

Do you use Swing components for the interface and let Swing repaint it all ?
Why additional panel double buffering if its enabled for the JFrame ?
Any complex logic anywhere ?

More overall information needed, I’d say.

Thank you for your answer.

There were a lot of lags at start (VisualVM showed that it was because of ImageFetcher and AWT EDT), and that is why I decided to improve the JPanel paint by using a double buffering software on it…
However, the problems remains the same without this doubleBuffering. If we forget about it you’ll find below part of the code. I think the main problem come from calling the swing painting with layeredPane.getGraphics.
How could i do to avoid it ?

JFrame :

w.createBufferStrategy(2);
BufferStrategy strategy = w.getBufferStrategy();
RenderingThreatHardBuffer renderingThread;

JLayeredPane layeredPane;


RenderingThreadHardBuffer :

while (true) {
Graphics g = strategy.getDrawGraphics();
layeredPane.getGraphics();
strategy.show();
}

JLayeredPane
JPanel map;
JPanel interfaceComponent1;
JPanel interfaceComponent2;

Double buffering is to avoid flickering, not lagging.

while (true) {
Graphics g = strategy.getDrawGraphics();
layeredPane.getGraphics();
strategy.show();
}

Is that original code ? Cause lines 2+3 have no effect.

Again, how do you draw the interface ? Swing, pixel juggling ? What are the panels for ?
Set ignore repaint on JFrame ?

Thank you for all your answers.
To simplify the code and take the problems stepby step, i tried to kept only the Frame and the buffer strategy.
Unfortunately, it seems i have another problem : the code behind should normally be working (as far I know…) unfortunatelly the line appears with a probability of 50%…

I tried it on a friend’s computer and it is working perfectly fine… How is that possible ?

The main class
public class main {
public static void main(String[] args) {
Fenetre fen = new Fenetre();

}

}

The Frame class, “Fenetre”

import java.awt.Cursor;
import java.awt.Frame;
import java.awt.Graphics;

import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ItemEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import javax.imageio.ImageIO;


public class Fenetre extends Frame implements ComponentListener {

	int fenHaut = 0;
	int fenLarg = 0;
	
	
	 BufferStrategy strategy; 
	 private Graphics           backBuffer          = null;
	 private boolean            initiated           = false;

	
	
	public Fenetre() {
		fenHaut = 720;
		fenLarg = 950;
		this.setSize(fenLarg, fenHaut);
		this.setLocationRelativeTo(null);
		this.setResizable(true);
		this.setTitle("Alphamega");
		
		addComponentListener(this);

		this.addWindowListener(new WindowAdapter() {
			 
	        public void windowClosing(WindowEvent e) {
	        System.exit(0);
	        }
	    });
		this.setVisible(true);
		graphicalRender();
		
	}

	public void setVisible(boolean b) {
        super.setVisible(b);
        if (b & !initiated)
            init();
    }

    /**
     * initialise l'affichage 
     */
    private void init() {
    	
        setIgnoreRepaint(true);
        createBufferStrategy(2);
        strategy = getBufferStrategy();
        initiated = true;
    }
	
	
	public void componentHidden(ComponentEvent arg0) {
	}

	public void componentMoved(ComponentEvent arg0) {
	}

	public void componentResized(ComponentEvent arg0) {
	}

	public void componentShown(ComponentEvent arg0) {
	}
	
	
	
	public void graphicalRender(){
		backBuffer = strategy.getDrawGraphics();

		
		backBuffer.drawString("Can you see me ?", 100, 200 );
		backBuffer.dispose();
		strategy.show(); 
	}

}

You need a periodically called render loop.
Currently, you only render once right after setVisible().
At that time the UI stuff might not be necessarily ready to use, depending on your computer speed. Something like that, I’ say.

Don’t forget that when posting code in these forums, Riven has very kindly provided an easy-peasy way to insert syntax highlighted code snippets (the button with the hash sign in the post editor).