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 :

Faut-il libérer systématiquement les ressources de Graphics2D ?


Sujet :

Composants Java

  1. #1
    Membre Expert Avatar de rtg57
    Homme Profil pro
    Autodidacte
    Inscrit en
    Mars 2006
    Messages
    1 341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 341
    Par défaut Faut-il libérer systématiquement les ressources de Graphics2D ?
    Bonjour,

    lorsqu'on fait du dessin sur un composant comme un JPanel par exemple, on surcharge habituellement les:
    • paintComponent( Graphics G );
    • repaint( Rectangle r );

    etc...

    Dès que l'on veut faire du graphisme 'un peu' évolué, on utilise classiquement la bibliothèque Graphics2D, avec la classique ligne de code:
    Et surtout, on n'oublie pas à la fin de la procédure:
    Après observation du fonctionnement de mon application, je constate que paintComponent(), ou paint() peuvent être appelées des dizaines de fois d'affilée, au gré des évènements systèmes (re-dimensionnement de fenêtre, apparition / disparition, chevauchement de fenêtres...)

    La question que je me pose est: quelle serait la meilleure solution entre:
    • Créer et maintenir un objet Graphics2D attaché au composant durant toute sa durée de vie ?
    • Ou créer un objet Graphics2D systématiquement à l'entrée d'une procédure graphique, puis libérer systématiquement ses ressources à la sortie ?

    Cette seconde méthode a certainement un coût en gestion des ressources et en temps de traitement...
    Par contre, on est sûr à chaque fois d'avoir un objet G2D adapté au contexte

    La première solution permettrait probablement d'économiser du temps au système en évitant de réserver puis libérer de la ressource à chaque passage.
    Par contre, est-ce que l'objet G2D serait toujours conforme au contexte graphique de l'objet...

    J'avoue que je ne sais pas me décider sur le sujet.
    Qu'en pensez-vous ?

  2. #2
    Membre Expert Avatar de rtg57
    Homme Profil pro
    Autodidacte
    Inscrit en
    Mars 2006
    Messages
    1 341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 341
    Par défaut
    Hello,

    pour info, j'ai fait des essais en essayant de maintenir un objet Graphics2D au-delà des procédure de dessins paintComponent( Graphics G ); repaint( Rectangle r ); etc...
    Bon ben ça ne marche pas bien. Malgré que l'objet Graphics G transmis par le système semble être toujours le même, il y a certainement d'autres mécanismes qui entrent en jeu.

    L'affaire est donc résolue.

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 900
    Billets dans le blog
    54
    Par défaut
    Je pense qu'on est ici pile poil dans la ligne directrice du "Sun / Oracle a pondu par le passe des tas de didacticiels / livres avec toujours le même code dedans ou ils s'y prennent comme des pieds / ne gèrent pas bien les ressources et donc tout le monde fait comme eux depuis 20 ans."

    Personnellement, plutôt que de faire ça :

    Citation Envoyé par rtg57 Voir le message
    Et surtout, on n'oublie pas à la fin de la procédure:
    Je fais plutôt ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    gd2 = (Graphics2D)g.create(...);
    try {
       [...]
    } finally {
        gd2.dispose();
    }

    Du coup :
    1. Plutot que de dessiner directement dans le graphique qu'on a reçu en paramètre, on se crée une vue avec un clip. Ca permet par exemple de commencer avec le repère aux bonnes coordonnées en tenant compte de la bordure du composant.
    2. S'il y a besoin de libérer des ressources (après tout on est pas sur que dispose() serve a quelque chose -il est possible que ca soit utile par exemple sur les graphiques issus d'imprimantes), on le fait sur la vue, paske bon le graphique reçu en paramètre, il pourrait très bien être réutilisé ailleurs juste après.
    3. On fait dispose() même en cas d'erreur.


    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
    package test.paint;
     
    import javax.swing.*;
    import javax.swing.border.CompoundBorder;
    import javax.swing.border.EmptyBorder;
    import javax.swing.border.LineBorder;
    import java.awt.*;
     
    public final class Main extends JComponent {
        private static final int SIDE = 10;
        private static final TexturePaint TRANSPARENCY_PATTERN = createTransparencyPattern();
     
        public static void main(String... args) {
            SwingUtilities.invokeLater(Main::startEDT);
        }
     
        private static final void startEDT() {
            final var border = new CompoundBorder(new EmptyBorder(10, 10, 10, 10), new LineBorder(Color.BLACK, 1));
            final var content = new Main();
            content.setBorder(border);
            final var frame = new JFrame("Test");
            frame.setSize(800, 600);
            frame.setLayout(new BorderLayout());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(content, BorderLayout.CENTER);
            frame.setVisible(true);
        }
     
        private static final TexturePaint createTransparencyPattern() {
            final var ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            final var gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
            final var image = gc.createCompatibleImage(SIDE * 2, SIDE * 2, Transparency.OPAQUE);
            final var g2d = image.createGraphics();
            try {
                g2d.setColor(Color.WHITE);
                g2d.fillRect(0, 0, SIDE * 2, SIDE * 2);
                g2d.setColor(Color.LIGHT_GRAY);
                g2d.fillRect(SIDE, 0, SIDE, SIDE);
                g2d.fillRect(0, SIDE, SIDE, SIDE);
            } finally {
                g2d.dispose();
            }
            return new TexturePaint(image, new Rectangle(0, 0, SIDE * 2, SIDE * 2));
        }
     
        @Override
        public void paintComponent(final Graphics g) {
            super.paintComponents(g);
            final var insets = getInsets();
            final var size = getSize();
            final int canvasX = insets.left;
            final int canvasY = insets.top;
            final int canvasWidth = Math.max(0, size.width - insets.left - insets.right);
            final int canvasHeight = Math.max(0, size.height - insets.top - insets.bottom);
            if (canvasWidth > 0 && canvasHeight > 0) {
                final var g2d = (Graphics2D) g.create(canvasX, canvasY, canvasWidth, canvasHeight);
                try {
                    doPaint(g2d, canvasWidth, canvasHeight);
                } finally {
                    g2d.dispose();
                }
            }
        }
     
        protected void doPaint(final Graphics2D g2d, final int width, final int height) {
            g2d.setPaint(TRANSPARENCY_PATTERN);
            g2d.fillRect(0, 0, width, height);
            // [...]
        }
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  4. #4
    Membre Expert Avatar de rtg57
    Homme Profil pro
    Autodidacte
    Inscrit en
    Mars 2006
    Messages
    1 341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 341
    Par défaut
    Merci beaucoup Bouye pour ce retour sur le sujet.

    Je ne connaissais pas cette manière de procéder.
    Je vais regarder ton extrait de code d'un peu plus près.

    Bonne continuation...

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

Discussions similaires

  1. Libérer les ressources
    Par xokami35x dans le forum Langage
    Réponses: 10
    Dernier message: 09/09/2009, 20h48
  2. Libérer les ressources
    Par mouloudéen dans le forum ASP.NET
    Réponses: 1
    Dernier message: 18/03/2009, 09h46
  3. [SWT] Libérer les ressources
    Par soft0613 dans le forum SWT/JFace
    Réponses: 15
    Dernier message: 04/08/2008, 13h32
  4. Réponses: 3
    Dernier message: 09/10/2006, 19h22
  5. Libérer les ressources lors de la fermeture d'un programme
    Par Heliopraetor dans le forum DirectX
    Réponses: 10
    Dernier message: 14/09/2004, 19h15

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