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