Image de fond

Résolu
Replic4 Messages postés 8 Date d'inscription vendredi 31 mars 2006 Statut Membre Dernière intervention 11 août 2006 - 10 août 2006 à 11:17
snowfire166 Messages postés 1 Date d'inscription jeudi 20 mars 2008 Statut Membre Dernière intervention 2 avril 2008 - 2 avril 2008 à 22:02
Bonjour,


J'ai créé une fenêtre (JFrame) avec une image de fond en recréant un JComponent. Mon problème est de réussir à placer des objets au dessus sans cacher le reste de l'image par un JPanel.


Mon code :


public class MaFenetre extends JFrame
{
 MaFenetre()
 {
  ...


  // FondAvecImage("lien vers l'image") Hérite de JComponent
  this.setContentPane(new FondAvecImage("lien vers l'image"));
  
  // Code pour placer mes composants
  
  this.setVisible(true);


  ...
 }
}


Savez vous comment placer des composants comme des boutons, des labels sans ajouter de JPanel ? Ce qui viendrait devant l'image de fond !!


Ensuite, existe un Layout permettant de placer ses composants en utilisant des coordonnés ?


J'espère avoir été suffisament clair.


David

11 réponses

Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
11 août 2006 à 12:46
Salut,

bon je t'ai changé pas mal de choses dans ton code en esperant que tu comprennes bien les changements fait (j'ai testé ça fonctionne ici) :

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class JPanelImageBg extends JPanel{//JComponent { evite d'etendre de JComponent qd tu veux faire un panel

    private static final long    serialVersionUID        = 5885901521118705414L;
    public static final int        CENTRE                    = 0;
    public static final int        TEXTURE                    = 1;
    private int                    mode                    = CENTRE;
    private TexturePaint        texture                    = null;
    private BufferedImage        bufferedImage            = null;
   

    public static void main(String [] args){
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(3);
        f.setSize(new Dimension(300, 300));
        f.setLocationRelativeTo(null);
        JPanelImageBg bg = new JPanelImageBg("img.jpg", JPanelImageBg.CENTRE);
        for(int i = 1; i < 11; i++)//juste pour tester l'affichage
            bg.add(new JButton(""+i));
       
       
        f.setContentPane(bg);
        f.setVisible(true);
    }
   
   
    public JPanelImageBg(String fileName, int mode) {
        switch(mode){
            case TEXTURE://pour ne pas charger les ressources inutilisement
                this.mode = mode;
                this.texture = new TexturePaint(bufferedImage, new Rectangle(0, 0,
                        bufferedImage.getWidth(), bufferedImage.getHeight()));
                break;
            case CENTRE:               
            default:
                this.mode = CENTRE;
                this.bufferedImage = this.toBufferedImage(getToolkit()
                    .getImage(fileName));
                break;
        }       
    }

    public void paintComponent(Graphics g) {
        switch (mode) {
            case TEXTURE:
                if(texture != null){//petite securitee
                    Graphics2D g2d = (Graphics2D) g;
                    g2d.setPaint(texture);
                    g2d.fillRect(0, 0, getWidth(), getHeight());
                }
                break;
            case CENTRE:
                if(bufferedImage != null){//petite securitee
                    g.setColor(this.getBackground());
                    g.fillRect(0, 0, getWidth(), getHeight());
                    g.drawImage(bufferedImage, (getWidth() - bufferedImage
                            .getWidth()) / 2, (getHeight() - bufferedImage
                            .getHeight()) / 2, null);
                }
                break;
            //default:
                //super.paintComponents(g);//si tu le fais ici cela n'affichera jamais les composants
        }
        super.paintComponents(g);
    }

    /**
     * Transforme une image en bufferedImage
     * @param image l'image a transformer
     * @return Retourn l'image convertie ou null (si l'image source ete null)
     */
    private BufferedImage toBufferedImage(Image img) {
        if(img == null) return null;//si l'image est null pas besoin de continuer
        if (img instanceof BufferedImage)//si l'image est deja une instance de BufferedImage on la retourne
            return (BufferedImage) img;
       
        // On s'assure que l'image soit bien chargee
        img = new ImageIcon(img).getImage();

        //Determine si l'image contient ou non un pixel de transparence
        boolean hasAlpha = hasAlpha(img);

        int type;//type de couleur
       
        // On creer un BufferedImage ayant un format compatible avec l'environement graphique du pc
        BufferedImage bi = null;
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        try {
            //Maintenant on determine si le nouveau BufferedImage aura ou non un pixel de transparence
            type = Transparency.OPAQUE;
            if (hasAlpha) type = Transparency.BITMASK;

            // Creation de notre nouveau BufferedImage
            bi = ge.getDefaultScreenDevice()
                            .getDefaultConfiguration().
                                createCompatibleImage(
                                        img.getWidth(null), img .getHeight(null), type);
        } catch (HeadlessException e) {
            // Le systeme n'as pas d'ecran ?
        }

        if (bi == null) {
            // Si le BufferedImage precedement creer est null on en creer un avec un model par defaut
            type = BufferedImage.TYPE_INT_RGB;
            if (hasAlpha) type = BufferedImage.TYPE_INT_ARGB;
            bi = new BufferedImage(img.getWidth(null), img.getHeight(null), type);
        }

        // On copie l'image dans le BufferedImage
        Graphics g = bi.createGraphics();
        // maintenant on la dessine
        g.drawImage(img, 0, 0, null);
        g.dispose();
        return bi;
    }
   
    /**
     * Test si une image contient ou non un canal alpha
     * @param image l'image a tester
     * @return retourne vrai si elle en contien un
     */
    private boolean hasAlpha(Image image) {
        // si l'image et deja un BufferedImage alors pas besoin de checker le model de couleur
        if (image instanceof BufferedImage)
            return ((BufferedImage) image).getColorModel().hasAlpha();
        //utilisation d'un 'grabber' pour retrouver le model de couleur de l'image
        //normalement le grab du pixel en haut a gauche  est suffisant.
        PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
        try {
            if(!pg.grabPixels()) return false;
        } catch (InterruptedException e) {
        }
        // on check si le model de couleur correspond ou non a un chanel alpha
        return pg.getColorModel().hasAlpha();
    }
}

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
3
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
10 août 2006 à 11:50
Salut,

pense à fair super.paintComponents(graphics) dans le paintComponent de l'objet FondAvecImage

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
0
Replic4 Messages postés 8 Date d'inscription vendredi 31 mars 2006 Statut Membre Dernière intervention 11 août 2006
10 août 2006 à 14:31
J'ai bien mis fait le super.paintComponents(graphics). Je pense que ma technique ne doit pas être bonne car quand je fait juste :


this.setComponentPane(new FondAvecImage("lien vers l'image")); j'ai bien une image en fond de ma JFrame.

Mon problème, c'est que je veux ensuite placé divers composants et pour ca j'ajoute un JPanel avec un Layout. Ca cache l'image.

Je ne vois pas trop comment faire autrement.
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
10 août 2006 à 15:02
slaut,

montre le code

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Replic4 Messages postés 8 Date d'inscription vendredi 31 mars 2006 Statut Membre Dernière intervention 11 août 2006
10 août 2006 à 21:44
Voila le code :

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.*;

class Fond extends JFrame {
   
    // Sert à obtenir les dimensions de l'écran
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    JPanelImageBg WallPaper;
   
    BorderLayout flowManagement;
   
    menuBar Bar;
   
    public Fond ()
    {
        setUndecorated(true);
       
        // Sert à fermer l'application quand cette fenetre est fermée
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
        // Définie la taille de la fenetre
        setBounds(0,0,screenSize.width,screenSize.height);
       
        // Permet d'avoir la fenetre au dessus de la barre "windows"
        setAlwaysOnTop(true);
               
        JPanelImageBg WallPaper = new JPanelImageBg("img/bureau_1.png", 0);
        this.setContentPane(WallPaper);
       
        Bar = new menuBar("SOUTH"); // herite de JPanel
       
        this.setContentPane(Bar);      
    }

}

Je ne sais pas si ca peut aider
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
10 août 2006 à 22:01
Salut,

essai de faire plutot

JPanelImageBg wallPaper = new JPanelImageBg("img/bureau_1.png", 0);
this.setContentPane(WallPaper);
wallPaper.setLayout(new BorderLayout());
Bar = new menuBar("SOUTH"); // herite de JPanel
//veille que les composant que tu place ne soit pas opaque sinon tu ne verras plus l'image
wallPaper.add(Bar, BorderLayout.SOUTH); //ou autre 

sinon le code que je demande le plus c'est JPanelImageBg

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
0
Replic4 Messages postés 8 Date d'inscription vendredi 31 mars 2006 Statut Membre Dernière intervention 11 août 2006
11 août 2006 à 09:56
Voila la classe JPanelImageBg. Je tiens à préciser que ce n'est pas moi qui l'ai codé. Elle viens d'un autre site. (Je ne sais pas si je dois citer l'auteur, alors dans le doute je ne le fais pas):


import javax.swing.*;
import java.awt.*;
import java.awt.image.*;

public class JPanelImageBg extends JComponent
{
private int mode;
private TexturePaint texture;
private BufferedImage bufferedImage;

public static final int CENTRE = 0;
public static final int TEXTURE = 1;

JPanelImageBg( String fileName, int mode )
{ this.mode = mode;
this.bufferedImage = this.toBufferedImage(Toolkit.getDefaultToolkit().getImage(fileName));
this.texture = new TexturePaint(bufferedImage,new Rectangle(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight()));
}

public void paintComponent(Graphics g)
{ switch( mode )
{ case TEXTURE :
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(texture);
g2d.fillRect(0, 0, getWidth(), getHeight() );
break;
case CENTRE :
g.setColor(this.getBackground());
g.fillRect(0,0,getWidth(), getHeight() );
g.drawImage(bufferedImage,(getWidth()-bufferedImage.getWidth())/2,(getHeight()-bufferedImage.getHeight())/2,null);
break;
default :
super.paintComponents(g);
}
}


private BufferedImage toBufferedImage(Image image)
{ image = new ImageIcon(image).getImage();

BufferedImage bufferedImage = new BufferedImage( image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics g = bufferedImage.createGraphics();

g.setColor(Color.white);
g.fillRect(0, 0, image.getWidth(null),
image.getHeight(null));
g.drawImage(image, 0, 0, null);
g.dispose();
return bufferedImage;
}

}

Merci de ton aide en tout cas. En fait en ajoutant un Layout directement à l'objet WallPaper ca fonctionne nickel.

David
0
Replic4 Messages postés 8 Date d'inscription vendredi 31 mars 2006 Statut Membre Dernière intervention 11 août 2006
11 août 2006 à 10:12
On dirait qu'il n'a pas aimé mon précedent message alors je recommence :


import javax.swing.*;
import java.awt.*;
import java.awt.image.*;

public class JPanelImageBg extends JComponent
{
private int mode;
private TexturePaint texture;
private BufferedImage bufferedImage;

public static final int CENTRE = 0;
public static final int TEXTURE = 1;

JPanelImageBg( String fileName, int mode )
{ this.mode = mode;
this.bufferedImage = this.toBufferedImage(Toolkit.getDefaultToolkit().getImage(fileName));
this.texture = new TexturePaint(bufferedImage,new Rectangle(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight()));
}

public void paintComponent(Graphics g)
{ switch( mode )
{ case TEXTURE :
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(texture);
g2d.fillRect(0, 0, getWidth(), getHeight() );
break;
case CENTRE :
g.setColor(this.getBackground());
g.fillRect(0,0,getWidth(), getHeight() );
g.drawImage(bufferedImage,(getWidth()-bufferedImage.getWidth())/2,(getHeight()-bufferedImage.getHeight())/2,null);
break;
default :
super.paintComponents(g);
}
}


private BufferedImage toBufferedImage(Image image)
{ image = new ImageIcon(image).getImage();

BufferedImage bufferedImage = new BufferedImage( image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics g = bufferedImage.createGraphics();

g.setColor(Color.white);
g.fillRect(0, 0, image.getWidth(null),
image.getHeight(null));
g.drawImage(image, 0, 0, null);
g.dispose();
return bufferedImage;
}

}
0
Replic4 Messages postés 8 Date d'inscription vendredi 31 mars 2006 Statut Membre Dernière intervention 11 août 2006
11 août 2006 à 19:12
Bon et bien j'ai encore des trucs à apprendre. Ca fonctionne nickel.

Merci beaucoup
David
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
11 août 2006 à 19:18
Salut,

ba de rien , si il y a des choses obscure non comprise dans ce que j'ai fais dis le j'essayerai de te les expliquer.

PS: On ne peut pas tout savoir desuite sinon il n'y a plus de plaisir
RPS: normalement on valide la reponse de la personne qui t'aide

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
0
snowfire166 Messages postés 1 Date d'inscription jeudi 20 mars 2008 Statut Membre Dernière intervention 2 avril 2008
2 avril 2008 à 22:02
Bonsoir a tous,

D'abord merci a tous pour les explications fournies sur le forum!
J'aurais aimé savoir s'il était possible d'ajouter un Canvas au dessus d'une image de fond? j'ai bien essayé en mettant dans votre programme (dans le main) et en specifiant paint:

    public static void main(String [] args){
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(3);
        f.setSize(new Dimension(400, 300));
        f.setLocationRelativeTo(null);
        JPanelImageBg bg = new JPanelImageBg("logo_ustl.gif", JPanelImageBg.CENTRE);

        Canvas c = new Canvas();
        bg.add(c);

        f.setContentPane(bg);
        f.setVisible(true);

    }
 
    public void paint (Graphics g) {
       int x=3;  // initialisation des abscisses
       for (int y=15;y<200;y+=10) {
         g.drawString("+-----------+-----------+-----------+-----------+",x-2,y);
       }
    }

mais cela ne fonctionne pas... HELP ME s'il vous plait!
L'objectif final est d'afficher le contenu de quatre tas de carte sous la forme :

+-------------+-------------+-------------+-------------+
|                  |                  |                  |                  |
|                  |                  |                  |                  |
|    T   6      |      etc        |      etc       |       etc       |
+-------------+-------------+-------------+-------------+
|    TAS1     |    TAS2    |    TAS3    |   TAS4     |
+-------------+-------------+-------------+-------------+

voila un jar executable d'une version qui fonctionne telle que je veux (faite par moi) mais a laquelle je voudrais rajouter une image de fond : http://rapidshare.com/files/104375883/demo.jar.html et taper java -jar demo.jar

Merci d'avance

Kévin
0
Rejoignez-nous