IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants Java Discussion :

Problème paintComponent et JPanel


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2002
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2002
    Messages : 22
    Par défaut Problème paintComponent et JPanel
    Bonjour,

    Voila j'expose mon problème :

    J'ai une JFrame dans laquelle je dessine avec une rafraichissement régulier. Pour cela j'ai créé une classe JCanvas dérivant JPanel en redéfinissant paintComponent() pour dessiner et être rafraichie par repaint(). Jusque là pas de problèmes, tous ce dessine correctement avec le rafraichissement qui va bien et tout.
    Maintenant je veux pouvoir afficher de l'ihm pardessus mon JCanvas avec les des JPanel, JTextField, JBouton etc... Le problème est que lorsque j'ajoute un JPanel dans ma JFrame au lancement je le vois jusqu'au premier rafraichissement après lequel il disparait (il passe surement en arrière plan, enfin je suppose).

    Pour préciser comment sont imbriqués mes composants voici ce qui est fait :

    Une JFrame dans laquelle j'ajoute un JPanel en tant que contentPane.
    Ensuite j'ajoute un JPanel (GUIPanel) avec setOpaque(false) dans le contentPane.
    Puis j'ajoute mon JCanvas dans le contentPane.

    plusieurs précisions :

    - j'ai mit en MouseEvent sur le JPanel GUIPanel et même lorsque les éléments disparaissent un clic sur l'écran est bien capturé par le GUIPanel.
    - Si je ne lance pas le thread de rafraichissement les éléments du GUIPanel sont bien affiché pardessus mon JCanvas.
    - Si je demande un repaint() de mon GUIPanel dans le thread de rafraichissement les éléments clignote.

    Voila si quelqu'un avait une piste pour que mes éléments du GUIPanel reste toujours au premier plan je suis preneur. Merci.

  2. #2
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 052
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 052
    Par défaut
    Salut,

    Pourrais-tu poster ton code ?

  3. #3
    Membre averti
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2002
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2002
    Messages : 22
    Par défaut
    Bon je vais essayer de mettre l'essentielle du code.

    La partie de code le la main classe.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
     
    public class Launcher extends AbstractLauncher {
     
            ...
     
    	public void createWindow(){
    			window = new JFrame();
    			window.setSize(frameWidth, frameHeigth);
    			window.setBackground(Color.BLUE);
     
    			window.addKeyListener(new KeyAdapter(){
    				@Override
    				public void keyReleased(KeyEvent e) {
    					System.out.println("Key code : "+e.getKeyCode());
    					if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
    						System.out.println("Escape");
    						window.dispose();
    						System.exit(0);
    					}
    				}
    			});
     
    			JPanel content = new JPanel();
    			content.setSize(frameWidth, frameHeigth);
    			content.setLayout(null);
    			window.setContentPane(content);
     
    			contentGui = new JPanel();
    			contentGui.setSize(frameWidth, frameHeigth);
    			contentGui.setLayout(null);
    			contentGui.setOpaque(false);
    			content.add(contentGui);
    			contentGui.addMouseListener(new MouseAdapter(){
    				@Override
    				public void mouseReleased(MouseEvent e) {
    					System.out.println("content Gui clicked !");
    				}
    			});
     
    			canvas = new JCanvas();
    			canvas.setSize(frameWidth, frameHeigth);
    			canvas.setRenderer(rendererEngine);
    			content.add(canvas);
    			canvas.addMouseListener(new MouseAdapter(){
    				@Override
    				public void mouseReleased(MouseEvent e) {
    					System.out.println("canvas clicked !");
    				}
    			});
     
    			GuiText panel2 = new GuiText(Color.BLACK, true, 200, 25);
    			panel2.setCaretColor(Color.WHITE);
    			panel2.setForeground(Color.WHITE);
    			panel2.changePosition(IGuiElement.POS_CENTER, contentGui);
    			contentGui.add(panel2);
     
    			JPanel test = new JPanel();
    			test.setSize(100, 100);
    			contentGui.add(test);
    	}
     
    	@Override
    	public void run() {
    		rendererEngine.start();
    		DisplayMode displayMode = new DisplayMode(frameWidth, frameHeigth, 16, DisplayMode.REFRESH_RATE_UNKNOWN);
    		ScreenManager screen = new ScreenManager();		
    		screen.setFullScreen(displayMode, window);
    	}
     
    	public static void main(String[] args) {
    		Launcher launch = new Launcher(1024, 768);
    		launch.run();
    	}
    }
    Code du canvas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    public class JCanvas extends JPanel {
     
    	/**
             * Serial version UID
             */
    	private static final long serialVersionUID = 1L;
     
    	private AbstractRendererEngine renderer;
     
        @Override
        protected void paintComponent(Graphics g) {
        	super.paintComponent(g);
        	if(renderer != null){
        		Graphics2D g2d = (Graphics2D)g;
        		renderer.buildScreenRender(g2d);
        	}
        }
     
    	public AbstractRendererEngine getRenderer() {
    		return renderer;
    	}
     
    	public void setRenderer(AbstractRendererEngine renderer) {
    		this.renderer = renderer;
    	}
     
    }
    Code du renderer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    public class RendererEngine extends AbstractRendererEngine {
     
     
    	public RendererEngine(JCanvas canvas, Launcher launch) {
    		super(canvas, launch);
    	}
     
    	public RendererEngine(JCanvas canvas, Launcher launch, long sleep){
    		this(canvas, launch);
    		sleepTime = sleep;
    	}
     
    	public RendererEngine(Launcher launch, long sleep){
    		this(null, launch);
    		sleepTime = sleep;
    	}
     
    	@Override
    	public void init() {
    		// TODO Auto-generated method stub
     
    	}
     
    	@Override
    	public void buildScreenRender(Graphics2D g2d) {
    		if(getLauncher().getCurrentScene() != null 
    				&& getLauncher().getCurrentScene().isDraw()){
    			getLauncher().getCurrentScene().draw(g2d);
    		}
     
    	}
     
    	/**
             * Redéfinition de la méthode run
             */
    	@Override
    	public void run() {
    		while (running) {
    			try {
    				canvas.repaint();
    				thread.sleep(sleepTime);
    			} catch (InterruptedException e) {
    				running = false;
    				e.printStackTrace();
    			}
    		}
    	}
     
    	@Override
    	public void start() {
    		if(thread == null){
    			thread = new Thread(this);
    		}
    		super.start();
    	}
     
    	@Override
    	public void stop() {
    		if(thread != null && thread.isAlive()){
    			super.stop();
    		}
    	}
     
    }
    Voilà en espérant que ce soit suffisamment claire car mon architecture contient pas mal d'héritage donc je ne peut pas tout coller ici

  4. #4
    Membre éclairé Avatar de DjGonk
    Profil pro
    Inscrit en
    Février 2007
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 88
    Par défaut
    En effet tu fais appel à super.paintComponent(g); qui redessine ton composant avec son contenu, et ensuite tu dessines par dessus ton ui, donc tes composants sont derriere ton dessin.

    Soit tu enlèves l'appel à super.paintComponent(g); dans ta méthode paintComponent (à tester pour voir si il n'y a pas d'éffets indésirables)

    Soit tu passes par un PanelUI (MetalPanelUI ou BasicPanelUI) qui te permettra de repeindre ton panel comme tu le désires, en ajoutant une méthode qui permet de changer les valeurs de ce dessin. Ensuite tu n'as plus qu'a faire tonpanel.repaint(); après changement des valeurs de l'ui (donc si je ne me suis pas trompé ton canvas.repaint() );

  5. #5
    Membre averti
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2002
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2002
    Messages : 22
    Par défaut
    Déjà merci de ta réponse, mais je ne suis pas sûr d'avoir tout saisie.

    Pour le paintConponent() le supprimer ne change rien.

    Pour la solution avec le PanelUI je ne suis pas sûr de comprendre ton raisonnement mais je pense que ce n'est pas tout à fait dans le sans de mon problème.

    Pour faire simple par ce que mon premier message n'est pas forcément très claire:
    J'ai une JFrame dans laquelle j'ajoute un JPanel avec la méthode setContentPane().
    Dans ce JPanel j'ajoute deux autres JPanel, tout d'abord un JPanel nommé contentGUI (qui contiendra des objets graphiques style JTextField, JLabel ...etc), et un JCanvas nommé canvas qui dérive de JPanel.
    Le contenu du canvas est redessiné régulièrement par un thread et le contenu du contentGUI est dessiné pardessus mais pas régulièrement. Or lorsque le canvas ce redessine le contenu du contentGui disparait alors qu'il n'est pas affecté par le thread.
    Je pensais que comment j'avais redéfini la méthode paintComponent() de mon JCanvas seul ce qu'il y avait dedans serait modifié et pas les autres composants graphique de la frame.
    Voilà, et si je repaint() le contentGUI dans le thread son contenu clignote, c'est peut être à ce niveau la que tu parlais de PanelUI ?

  6. #6
    Membre éclairé Avatar de DjGonk
    Profil pro
    Inscrit en
    Février 2007
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 88
    Par défaut
    D'accord je comprend un peu mieux.

    En fait tu peux utiliser un JLayeredPane qui te permettra de faire une distinction entre ton panel canva sur une couche basse et ton autre panel avec les composants sur une couche un peu plus haute.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    ...
    JLayeredPane jLayeredPane = new JLayeredPane();
    jLayeredPane.add(getCanvas());
    jLayeredPane.setLayer(getCanvas(), JLayeredPane.DEFAULT_LAYER);
    getCanvas().setVisible(true);
    jLayeredPane.add(getPanelComposants());
    jLayeredPane.setLayer(getPanelComposants(),JLayeredPane.DEFAULT_LAYER+10);
    getPanelComposants().setVisible(true);
    ...
    //Pour redessiner tu passes par
    getCanvas().repaint();

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème affichage de JPanel
    Par spike2 dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 31/01/2010, 02h43
  2. Problème KeyListener et JPanel
    Par paintkiller dans le forum Composants
    Réponses: 6
    Dernier message: 30/10/2009, 23h22
  3. Problème affichage Image Jpanel
    Par lerorodu51 dans le forum NetBeans
    Réponses: 17
    Dernier message: 10/06/2009, 19h43
  4. problème avec un jpanel cliquable
    Par isoman dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 05/03/2009, 14h01
  5. Problème décalage du JPanel dans une JFrame a cause du JMenuBar
    Par matou72 dans le forum Agents de placement/Fenêtres
    Réponses: 5
    Dernier message: 09/03/2007, 20h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo