Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8178091

some lag on animation when using panel.repaint() to refresh the screen

XMLWordPrintable

      FULL PRODUCT VERSION :
      openjdk version "1.8.0_121"
      OpenJDK Runtime Environment (build 1.8.0_121-8u121-b13-0ubuntu1.16.04.2-b13)
      OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux linux 4.4.0-70-generic #91-Ubuntu SMP Wed Mar 22 12:47:43 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      when we want to animate something we use Panel.repaint() each time
      to refresh the screen of jpanel elements
      but in java 8, there is some lag on animation

      REGRESSION. Last worked in version 7u80

      ADDITIONAL REGRESSION INFORMATION:
      java version "1.7.0_79"
      Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
      Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      for example:
      create a panel and a circle under it ,
      then a method who animate the circle , just move it for example,
      so we move (PosX++20; then we refreshed thanks to pan.repaint(); )

      and a Thread.sleep(300) ; for example or a Timer.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      WITH java 8 :
      the animation lag

      WITH java7 : it works well
      ACTUAL -
      WITH java 8 :
      the animation lag

      WITH java7 : it works well

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      no message error because it is visual bug

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.Color;
      import java.awt.Graphics;
      import javax.swing.JPanel;

      import java.awt.Dimension;
      import javax.swing.JFrame;

      public class Fenetre extends JFrame {

        public static void main(String[] args) {
          new Fenetre();
        }

        private Panneau pan = new Panneau();

        public Fenetre() {
          this.setTitle("Animation");
          this.setSize(300, 300);
          this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          this.setLocationRelativeTo(null);
          this.setContentPane(pan);
          this.setVisible(true);

          go();
        }

        private void go() {
          // Les coordonnées de départ de notre rond
          int x = pan.getPosX(), y = pan.getPosY();
          // Le booléen pour savoir si l'on recule ou non sur l'axe x
          boolean backX = false;
          // Le booléen pour savoir si l'on recule ou non sur l'axe y
          boolean backY = false;

          // Dans cet exemple, j'utilise une boucle while
          // Vous verrez qu'elle fonctionne très bien
          while (true) {
            // Si la coordonnée x est inférieure à 1, on avance
            if (x < 1)
              backX = false;
            // Si la coordonnée x est supérieure à la taille du Panneau moins la taille du rond, on recule
            if (x > pan.getWidth() - 50)
              backX = true;
            // Idem pour l'axe y
            if (y < 1)
              backY = false;
            if (y > pan.getHeight() - 50)
              backY = true;

            // Si on avance, on incrémente la coordonnée
            // backX est un booléen, donc !backX revient à écrire
            // if (backX == false)
            if (!backX)
              pan.setPosX(++x);
            // Sinon, on décrémente
            else
              pan.setPosX(--x);
            // Idem pour l'axe Y
            if (!backY)
              pan.setPosY(++y);
            else
              pan.setPosY(--y);

            // On redessine notre Panneau
            pan.repaint();
            // Comme on dit : la pause s'impose ! Ici, trois millièmes de seconde
            try {
              Thread.sleep(10);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
        }
      }
       class Panneau extends JPanel {

        private int posX = -50;
        private int posY = -50;

        public void paintComponent(Graphics g) {
          // On décide d'une couleur de fond pour notre rectangle
          g.setColor(Color.white);
          // On dessine celui-ci afin qu'il prenne tout la surface
          g.fillRect(0, 0, this.getWidth(), this.getHeight());
          // On redéfinit une couleur pour notre rond
          g.setColor(Color.red);
          // On le dessine aux coordonnées souhaitées
          g.fillOval(posX, posY, 50, 50);
        }

        public int getPosX() {
          return posX;
        }

        public void setPosX(int posX) {
          this.posX = posX;
        }

        public int getPosY() {
          return posY;
        }

        public void setPosY(int posY) {
          this.posY = posY;
        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      to fix this bug :
      each time we write JPanel.repaint();
      add :
      Toolkit.getDefaultToolkit().sync();


      then it works well even in java 8

      SUPPORT :
      YES

            aniyogi Avik Niyogi (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: