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 :

Optimisation d'affichage : ralentissements, scintillements, redimensionnement.


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut Optimisation d'affichage : ralentissements, scintillements, redimensionnement.
    Bonsoir à tous,

    Je suis débutant en Java et j'ai quelques questions concernant les interfaces graphiques.

    J'ai effectué une recherche rapidement et n'ai trouvé aucune réponse exacte à mes questions, donc désolé si ces questions ont déjà été posées.

    Voici mon problème :
    J'essais actuellement de développer une petite application pour simuler le déplacement de voitures sur une route.
    J'ai donc une classe Voiture, une classe Route, et une classe Fenetre qui me permet de faire un affichage graphique.

    - Premierement j'utilise TexturePaint pour que mes images ne soient pas déformées mais reproduite, la fonction suivante s'en charge :
    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
     
    public Graphics2D DessinerTextures(Graphics g){
            //Création d'un graphics 2d
            Graphics2D g2d = (Graphics2D)g;
            //Création de la BufferedImage
            ImageIcon image_herbe = new ImageIcon("herbe.jpg");
            BufferedImage buffImg_herbe = new BufferedImage(image_herbe.getIconWidth(), image_herbe.getIconHeight(), BufferedImage.TYPE_INT_RGB);
            //initialisation de l'images
            Graphics2D g2d_herbe = buffImg_herbe.createGraphics();
            g2d_herbe.drawImage(image_herbe.getImage(), 0, 0, this);
            //création du rectangle aux dimension de la texture de fond
            Shape imgRect_herbe = new Rectangle2D.Double(0.0, 0.0, buffImg_herbe.getWidth(), buffImg_herbe.getHeight());
             //Création du TexturePaint
            TexturePaint texture_herbe = new TexturePaint(buffImg_herbe, imgRect_herbe.getBounds2D());
            //Création des shapes
            Shape rectShapeHaut = new Rectangle2D.Double(jScrollPane1.getX(),jScrollPane1.getY(),route.longueur(),123);
            Shape rectShapeBas = new Rectangle2D.Double(jScrollPane1.getX(),jScrollPane1.getY()+route.largeur()+123,route.longueur(),jScrollPane1.getHeight());    
            //dessine les rectangles remplis avec les textures
            g2d.setPaint(texture_herbe);
            g2d.fill(rectShapeHaut);
            g2d.fill(rectShapeBas);
            return g2d;
        }
    - J'ai ensuite ça qui paint les textures et les voitures :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     public void paint(Graphics g) {
            DessinerTextures(this.getGraphics());
            for (int voie = 0; voie < route.nbVoies(); voie++)
    	    for (int i = 0; i < route.longueur(); i++) 
                      if (existeVoiture(voie,i)) {
                        ImageIcon img_voiture = new ImageIcon("voiture_rouge.jpg");
                        Image image_voiture = img_voiture.getImage();
                        ImageObserver image_voiture_obs = img_voiture.getImageObserver();
                        g2d.drawImage(image_voiture,jScrollPane1.getX()+(int)route.vehicule(voie,i).position,jScrollPane1.getY()+133+20*voie,image_voiture_obs);
                      }
    }
    Problème : le thread étant rafraichi toute les 30ms, ca rame beaucoup et l'image scintille !
    De plus, là apparement je ne dessine pas dans mon jScrollPane mais par dessus donc les scrolbars ne s'affichent pas l'orsque le dessin est plus grand que le jScrollPane, et je ne sais pas comment faire.

    Voici une petite image de l'interface pour vous donner une petite idée :


    En résumé voici ce que je souhaiterais :
    - suivant la longueur de l'autoroute une scrollbar horizontal doit apparaître.
    - l'éxecution doit être fluide, sans scintillements.

    Comment faire ? mon code est-il otpimisé ?

    Merci à tous.
    A vous lire.

  2. #2
    Membre chevronné Avatar de broumbroum
    Profil pro
    Inscrit en
    Août 2006
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 406
    Par défaut double buffering optimisé
    salut!
    A mon avis c'est tout à fait bien codé, mais ton idée serait mieux réalisée avec un buffer image pour l'optimisation du framerate puis éventuellement se passer d'une texturepaint qui n'a pas forcément plus de sens qu'une image répétée "bufferisée".
    Ensuite pour cequi est d'un scrolling horizontal, ça m'intéresse aussi de connaitre la solution...
    Double-Buffer c'est dans les sources java.

  3. #3
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    OK je vais regarder comment ca marche et j'essais ça demain.
    Merci de ta réponse.

  4. #4
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    Bon ca rame un peu moins, ca scintille plu mais le déplacement des voitures n'est toujours pas fluide.

    J'ai été obligé de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread thread = new Thread();
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RenderingThread renderingThread = new RenderingThread();
    car il ne trouve pas la class RenderingThread (même si je fait fixImports il me met : "No imports found for the following types : RenderingThread".
    C'est grave ?

    J'ai essayé aussi ça mais ca n'a pas l'air de changer grand chose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /** Désactivation de l'anti-aliasing */
    g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
    g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
    /** Demande de rendu rapide */
    g2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
    g2D.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
    g2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
    g2D.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
    Apparement il n'aime pas le texturePaint mais je n'arrive pas à faire autrement.

    Une idée ?

  5. #5
    Membre Expert
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Par défaut
    Bonjour,

    quelques remarques sur la méthode DessinerTextures :
    - pour avoir une BufferedImage à partir d'un fichier, utilise ImageIO.read(), ça ne prend qu'une ligne et c'est ce qu'il y a de plus efficace
    - en fait, tu lis le fichier image à chaque fois que tu actualises l'affichage ! Pas étonnant que ça rame La TexturePaint et les images, il faut les initialiser dans le constructeur, et puis tu ne t'en sers que pour les lire.

    Concernant le scroll :
    - il faut que tu mettes tout ce code dans une classe qui hérite de JPanel. Tu surcharges la méthode getPreferredSize pour renvoyer la longueur multipliée par le nombre de pixel correspondant à une unité de longueur.
    Enfin, tu mets ce JPanel dans un JScrollPane, et là ça ira tout seul.

    Voici un petit peu de code pour m'expliquer un peu mieux :
    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
    public class RoadView extends JPanel {
     
      private TexturePaint paintHerbe, paintRoute;
     
      ...
     
      public RoadView() {
        // on initialise les textures une bonne fois pour toutes
        BufferedImage img = ImageIO.read("herbe.jpg");
        paintHerbe = new TexturePaint(img, new Rectangle(0, 0, img.getWidth(), img.getHeight()));
     
        img = ImageIO.read("route.jpg");
        paintRoute = new TexturePaint(img, new Rectangle(0, 0, img.getWidth(), img.getHeight()));
     
        ...
       }
     
      public void dessinerTextures(Graphics2D g) {
     
        // dessiner l'herbe
        g.setPaint(paintHerbe);
        g.fillRect(0, 0, this.getWidth(), 123);
     
        g.fillRect(0, 123 + route.largeur(), this.getWidth(), this.getHeight() - 123 - route.largeur());
     
        // dessiner la route
        ...
      }
     
      public void paintComponent(Graphics graphics) {
     
        Graphics2D g = (Graphics2D) graphics;
        dessinerTextures(g);
        // ta boucle pour dessiner des voitures
        ...
      }
    }
     
    // dans une autre classe
    JScrollPane sp = new JScrollPane(new RoadView());
    maJFrame.getContentPane().add(sp);
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  6. #6
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    Merci de ta réponse Xavlours.
    J'ai fait comme tu m'a dit pour les texturePaint et ca ne rame plus donc merci.

    Cependant je n'arrive toujours pas à avoir les scrollbars dans mon JScrollPane.

    J'ai maintenant ceci :

    - une classe PanelRoute contenant le Jpanel où je dessine le dessin, et c'est là que je fait le SetPreferedSize (non?) :
    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
     
    public class PanelRoute extends javax.swing.JPanel {   
     
         private TexturePaint texture_herbe, texture_asphalte;
     
         public PanelRoute() {
            initComponents();
            setVisible(true);
            jPanel1.setPreferredSize(new Dimension(Main.autoroute.longueur()+30,500));
            texture_herbe = CreerTexture("herbe.jpg");
            texture_asphalte = CreerTexture("asphalte.jpg");
        }
     
         public TexturePaint CreerTexture(String UrlImage) {...}
         public Graphics2D DessinerTextures(Graphics g) {...}
         public Graphics2D DessinerRoute(Graphics g) {...}
         public Graphics2D DessinerVehicules(Graphics g) {...}
     
         public void paintComponent(Graphics g) {
            DessinerTextures(buffer);
            DessinerRoute(buffer);
            DessinerVehicules(buffer);
        }
    - ma classe Fenetre qui contient un jPanel (contenant un menu), et un jScrollPane dans lequel doit apparaître le dessin.

    Mais où est-ce que je doit placer ces lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    JScrollPane sp = new JScrollPane(new RoadView());
    maJFrame.getContentPane().add(sp);
    Dans le constructeur ?
    Car j'ai déjà un JScrollPane jScrollPane1.

    Ca fait 3 heures que je suis dessus j'ai essayé diverses choses mais rien ne fonctionne

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

Discussions similaires

  1. [C++ .Net 1.1] Comment optimiser l'affichage ?
    Par juliano_bipso dans le forum C#
    Réponses: 5
    Dernier message: 03/08/2006, 19h54
  2. Optimiser l'affichage
    Par loic_86 dans le forum 2D
    Réponses: 5
    Dernier message: 29/04/2006, 17h52
  3. Problème d'affichage lors du redimensionnement
    Par sidi.elmoctar dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 12/04/2006, 09h44
  4. Optimiser l'affichage d'un fichier XML de grosse taille...
    Par UnPeuPerdu dans le forum XML/XSL et SOAP
    Réponses: 11
    Dernier message: 03/06/2004, 17h01

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