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

AWT/Swing Java Discussion :

Plusieurs couches transparentes


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Par défaut Plusieurs couches transparentes
    Bonjour,

    j'ai un petit problème lorsque je superpose plusieurs couches transparentes.

    J'ai un composant en partie transparent que je redessine au passage de la souris.
    Cela fonctionne bien lorsque le composant parent n'a aucune transparence.

    Malheureusement, lorsque le parent est translucide (0 < alpha < 1), à chaque fois que je redessine le composant, les parties transparentes sont 'redessinées' alors qu'elles ne devraient pas l'être. Résultat : les regions du parents sous le composant deviennent de moins en moins translucide.

    Pour les détails :
    Le composant en partie transparent est:
    - un JPanel,
    - non opaque,
    - la méthode paintComponent() est redéfinie pour dessiner des formes simples genre un cercle (d'où les parties transparentes).

    Le composant parent qui pose problème est:
    - un JPanel,
    - opaque,
    - avec une couleur de background : new Color(255, 0, 0, 128) donc rouge transparente à 50%.

    Savez-vous comment je peut éviter de redessiner les parties du parent sous la transparence (ou sous tout le composant)?

  2. #2
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Peux-tu nous faire une appli simple en un seul fichier source qui reproduise le phénomène, pour que l'on puisse l'expérimenter ?

  3. #3
    Membre émérite
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Par défaut
    Bien sûr.

    Voici un exemple avec un cas qui marche et l'autre qui pose problème.
    En passant plusieurs fois la souris sur celui de gauche, vous verrez le fond devenir de plus en plus rouge.

    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
     
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
     
    public class Exemple extends JFrame {
     
        public static void main(final String[] pArgs) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new Exemple().setVisible(true);
                }
            });
        }
     
        public Exemple() {
            super("Exemple");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
            // Le fond bleu
            final JPanel lBackground = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 20));
            lBackground.setOpaque(true);
            lBackground.setBackground(Color.BLUE);
            setContentPane(lBackground);
     
            // Le parent rouge translucide
            final JPanel lParent = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 20));
            lParent.setOpaque(true);
            lParent.setBackground(new Color(128, 0, 0, 64));
            getContentPane().add(lParent);
     
            // Le composant sur fond translucide
            final JPanel lComponent = new JPanel() {
     
                @Override
                public void paintComponent(final Graphics pGraph) {
                    pGraph.setColor(getForeground());
                    pGraph.fillOval(10, 10, 180, 180);
                }
            };
            lComponent.addMouseListener(new MouseAdapter() {
     
                @Override
                public void mouseEntered(final MouseEvent pE) {
                    lComponent.setForeground(Color.GREEN);
                }
     
                @Override
                public void mouseExited(final MouseEvent pE) {
                    lComponent.setForeground(Color.PINK);
                }
            });
     
            lComponent.setOpaque(false);
            lComponent.setPreferredSize(new Dimension(200, 200));
            lParent.add(lComponent);
     
            // Le composant sur fond non translucide
            final JPanel lComponent2 = new JPanel() {
     
                @Override
                public void paintComponent(final Graphics pGraph) {
                    pGraph.setColor(getForeground());
                    pGraph.fillOval(10, 10, 180, 180);
                }
            };
            lComponent2.addMouseListener(new MouseAdapter() {
     
                @Override
                public void mouseEntered(final MouseEvent pE) {
                    lComponent2.setForeground(Color.GREEN);
                }
     
                @Override
                public void mouseExited(final MouseEvent pE) {
                    lComponent2.setForeground(Color.PINK);
                }
            });
     
            lComponent2.setOpaque(false);
            lComponent2.setPreferredSize(new Dimension(200, 200));
            lBackground.add(lComponent2);
     
            pack();
            setLocationRelativeTo(null);
        }
    }

  4. #4
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Merveilleux, cela devient un véritable plaisir que de rechercher une solution dans ces conditions, il faudrait te donner un prix !

    Après avoir perdu quelques temps à m'emerveiller de ta petite démo, je suggère de changer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            // Le parent rouge translucide
            final JPanel lParent = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 20));
            lParent.setOpaque(true);
            lParent.setBackground(new Color(128, 0, 0, 64));
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            // Le parent rouge translucide
            final JPanel lParent = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 20));
            lParent.setOpaque(false); // ICI.
            lParent.setBackground(new Color(128, 0, 0, 64));
    En effet, je ne pense pas qu'un composant rempli de couleur translucide puisse être désigné d'opaque ; je présume que ainsi cela oblige swing à provoquer le redessin des composants du dessous, alors que quand le composant est opaque, swing considère, probablement avec raison, que c'est inutile, alors que c'est faussement juste, n'est-ce pas.

    Un autre conseil aussi, je crois qu'il est utile de dessiner lors du paint tout le composant ou au moins tout le clip, même si c'est pour y mettre du transparent total ; cela empêche des bugs pour le cas où le contexte graphique donné en paramètre se compose de pixels résiduels.

  5. #5
    Membre émérite
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Par défaut
    Merci pour cette réponse rapide

    Le raisonnement me satisfait, et pour compléter ta réponse, j'ai surchargé paintComponent pour le parent:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    // Le parent rouge translucide
            final JPanel lParent = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 20)) {
            	@Override
                public void paintComponent(final Graphics pGraph) {
                    pGraph.setColor(getBackground());
                    pGraph.fillRect(0, 0, getWidth(), getHeight());
                }
            };
    Sinon, le setOpaque(false) rendait le panel invisible.

    Avec ces deux modifs, ça marche!!!!

    Un grand merci à toi!

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

Discussions similaires

  1. Plusieurs couches en SDL?
    Par Disciple195 dans le forum SDL
    Réponses: 4
    Dernier message: 19/06/2007, 16h23
  2. Novice : plusieurs couches de panneaux
    Par tomagold dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 16/03/2007, 16h06
  3. Plusieurs couches Graphics sur JPanel, etc..
    Par aristeas dans le forum AWT/Swing
    Réponses: 3
    Dernier message: 17/02/2007, 09h59
  4. [AWT] plusieurs couches
    Par ®om dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 04/10/2006, 15h17
  5. Gestion de plusieurs couches d'affichage
    Par esteban63 dans le forum Windows
    Réponses: 2
    Dernier message: 08/03/2006, 21h21

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