-
Bug
-
Resolution: Unresolved
-
P3
-
7u11
FULL PRODUCT VERSION :
java: 1.7.0_11
ADDITIONAL OS VERSION INFORMATION :
Mac OS X 10.8.2
EXTRA RELEVANT SYSTEM CONFIGURATION :
application was started with JavaWebstart
A DESCRIPTION OF THE PROBLEM :
Our fat swing application " ClassWizard " behaves unprofessional slow. While dragging elements there is not a smooth liquid moving but a slow moving with jumping and flickering elements. The reason of this is the fact, that the double buffered painting of offscreen image is 8 times slower then in java 6.
REGRESSION. Last worked in version 6u31
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
I have added a small application to reproduce the bug. Start the application under java 7 and java 6 and wait 1 minute until the drawing of a rectangle at 2 different positions at an interval of 25 milliseconds has stopped. Then close the application by the red window button. A Log file " RuntimeTest " is written to the users home directory. It contains the time sampled for the paint and paintComponent methods of the JPanel. The time sampled for the paint method is 8 times higher then under java 6.
log file under java 6:
Mac OS X 10.6.8 java: 1.6.0_37
count1: 2000 mess1: 937 time spend in paint
count2: 2000 mess2: 430 time spend in paintComponent
logfile under java 7
Mac OS X 10.8.2 java: 1.7.0_11
count1: 1995 mess1: 7774 time spend in paint
count2: 1995 mess2: 473 time spend in paintComponent
7774 millisec is 8 times higher then 937 millisec
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
double buffered paint Method in java 7 is as fast as in java 6
ACTUAL -
double buffered paint Method in java 7 is 8 times slower then in java 6.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.classwizard.cw;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;
public class ClassWizard extends Object{
public static void main(String args[]) throws Exception{
try{
RuntimeTestFrame ket = new RuntimeTestFrame();
GJApp.launch(ket, " RuntimeTest " ,0,0,700,700,null);
}catch (Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
class GJApp extends WindowAdapter{
public static void launch(final RuntimeTestFrame f, String title,final int x, final int y,final int w, int h,String propertiesFilename){
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f.addWindowListener(new WindowAdapter(){
public void windowClosed(WindowEvent e){
f.closefile();
System.exit(0);
}
});
}
}
class RuntimeTestFrame extends JFrame{
protected JDesktopPane desktopPane = new JDesktopPane();
protected Page worksheet = null;
PrintWriter writer = null;
protected File outfile = null;
boolean _even = true;
int _flickercount = 0;
javax.swing.Timer _timer = null;
public RuntimeTestFrame() throws Exception{
String user_home = System.getProperty( " user.home " );
String filepath = user_home + " /RuntimeTest.txt " ;
outfile = new File(filepath);
writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfile), " UTF-8 " )));
JComponent contentPane = (JComponent)getContentPane();
contentPane.setDoubleBuffered(true);
worksheet = new Page( " Worksheet " ,true,false,true,true,writer,this);
desktopPane.add(worksheet);
contentPane.add(desktopPane,BorderLayout.CENTER);
worksheet.setPreferredSize(new Dimension(500, 500));
Rectangle bounds2 = new Rectangle(0, 0, 500, 500);
worksheet.setBounds(bounds2);
String osname = System.getProperty( " os.name " );
String osversion = System.getProperty( " os.version " );
String java_version = System.getProperty( " java.version " );
writer.print(osname + " " + osversion + " java: " + java_version + "
" );
worksheet.setVisible(true);
desktopPane.revalidate();
// move the carea 1000 times for and back and sample time spend
_timer = new javax.swing.Timer(25, new ActionListener(){
public void actionPerformed(ActionEvent evt){
try{
if(_even == true){
worksheet.repaint();
_even = false;
}
else{
worksheet.repaint();
_even = true;
}
_flickercount++;
if(_flickercount == 2000){
_timer.stop();
writer.print( " count1: " + worksheet.count1 + " mess1: " + worksheet.mess1 + " time spend in paint " + "
" );
writer.print( " count2: " + worksheet.count2 + " mess2: " + worksheet.mess2 + " time spend in paintComponent " + "
" );
}
}
catch (Exception ex){
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
});
_timer.start();
}
public void closefile(){
writer.flush();
writer.close();
}
}
class Page extends JInternalFrame
{
long mess1 = 0;
long mess2 = 0;
int count1 = 0;
int count2 = 0;
protected RuntimeTestFrame _owner = null;
protected PrintWriter _writer = null;
protected Canvas canvas = null; // drawarea of page
protected JScrollPane _sp = null;
public Page(String title,boolean resizable, boolean closable, boolean maximizable, boolean iconifiable,PrintWriter writer,RuntimeTestFrame owner) throws Exception{
super(title,resizable,closable,maximizable,iconifiable);
_writer = writer;
_owner = owner;
JComponent contentPane = (JComponent)this.getContentPane();
canvas = new Canvas(writer,this);
_sp = new JScrollPane(canvas);
contentPane.add(_sp,BorderLayout.CENTER);
canvas.setBackground(Color.WHITE);
canvas.setSize(new Dimension(500,500));
}
public void displayRectangle(Graphics g){
Color boxcolor = new Color(0, 250, 0);
g.setColor(boxcolor);
if(_owner._even == true){
Rectangle r1 = new Rectangle(100, 100, 100, 100);
g.fillRect(r1.x, r1.y, r1.width, r1.height);
}else{
Rectangle r1 = new Rectangle(300, 300, 100, 100);
g.fillRect(r1.x, r1.y, r1.width, r1.height);
}
}
}
class Canvas extends JPanel{
PrintWriter _writer = null;
Page _page = null;
Image offscreen = null;
public Canvas(PrintWriter writer, Page page) throws Exception{
super();
_writer = writer;
_page = page;
}
@Override
public void paint(Graphics g){
long tmess1 = System.currentTimeMillis();
try{
Rectangle r222 = g.getClipBounds();
if(offscreen == null){
int width = getSize().width;
int height = getSize().height;
offscreen = createImage(width, height);
}
Graphics og = offscreen.getGraphics();
og.setClip(r222.x, r222.y, r222.width, r222.height);
super.paint(og); // all drawing into offsreenbuffer
Rectangle clip = g.getClipBounds();
// copy offsreenbuffer to screen in changed rectangle
g.drawImage(offscreen, clip.x, clip.y,clip.x+clip.width,clip.y+clip.height,clip.x, clip.y,clip.x+clip.width,clip.y+clip.height, null);
og.dispose();
}catch (Exception ex){
System.out.println(ex.getMessage());
ex.printStackTrace();
}
tmess1 = System.currentTimeMillis() - tmess1;
_page.mess1 += tmess1;
_page.count1++;
}
@Override
public void paintComponent(Graphics g){
long tmess2 = System.currentTimeMillis();
try{
super.paintComponent(g);
_page.displayRectangle(g);
}catch (Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
tmess2 = System.currentTimeMillis() - tmess2;
_page.mess2 += tmess2;
_page.count2++;
}
}
---------- END SOURCE ----------
SUPPORT :
YES
java: 1.7.0_11
ADDITIONAL OS VERSION INFORMATION :
Mac OS X 10.8.2
EXTRA RELEVANT SYSTEM CONFIGURATION :
application was started with JavaWebstart
A DESCRIPTION OF THE PROBLEM :
Our fat swing application " ClassWizard " behaves unprofessional slow. While dragging elements there is not a smooth liquid moving but a slow moving with jumping and flickering elements. The reason of this is the fact, that the double buffered painting of offscreen image is 8 times slower then in java 6.
REGRESSION. Last worked in version 6u31
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
I have added a small application to reproduce the bug. Start the application under java 7 and java 6 and wait 1 minute until the drawing of a rectangle at 2 different positions at an interval of 25 milliseconds has stopped. Then close the application by the red window button. A Log file " RuntimeTest " is written to the users home directory. It contains the time sampled for the paint and paintComponent methods of the JPanel. The time sampled for the paint method is 8 times higher then under java 6.
log file under java 6:
Mac OS X 10.6.8 java: 1.6.0_37
count1: 2000 mess1: 937 time spend in paint
count2: 2000 mess2: 430 time spend in paintComponent
logfile under java 7
Mac OS X 10.8.2 java: 1.7.0_11
count1: 1995 mess1: 7774 time spend in paint
count2: 1995 mess2: 473 time spend in paintComponent
7774 millisec is 8 times higher then 937 millisec
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
double buffered paint Method in java 7 is as fast as in java 6
ACTUAL -
double buffered paint Method in java 7 is 8 times slower then in java 6.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.classwizard.cw;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;
public class ClassWizard extends Object{
public static void main(String args[]) throws Exception{
try{
RuntimeTestFrame ket = new RuntimeTestFrame();
GJApp.launch(ket, " RuntimeTest " ,0,0,700,700,null);
}catch (Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
class GJApp extends WindowAdapter{
public static void launch(final RuntimeTestFrame f, String title,final int x, final int y,final int w, int h,String propertiesFilename){
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f.addWindowListener(new WindowAdapter(){
public void windowClosed(WindowEvent e){
f.closefile();
System.exit(0);
}
});
}
}
class RuntimeTestFrame extends JFrame{
protected JDesktopPane desktopPane = new JDesktopPane();
protected Page worksheet = null;
PrintWriter writer = null;
protected File outfile = null;
boolean _even = true;
int _flickercount = 0;
javax.swing.Timer _timer = null;
public RuntimeTestFrame() throws Exception{
String user_home = System.getProperty( " user.home " );
String filepath = user_home + " /RuntimeTest.txt " ;
outfile = new File(filepath);
writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfile), " UTF-8 " )));
JComponent contentPane = (JComponent)getContentPane();
contentPane.setDoubleBuffered(true);
worksheet = new Page( " Worksheet " ,true,false,true,true,writer,this);
desktopPane.add(worksheet);
contentPane.add(desktopPane,BorderLayout.CENTER);
worksheet.setPreferredSize(new Dimension(500, 500));
Rectangle bounds2 = new Rectangle(0, 0, 500, 500);
worksheet.setBounds(bounds2);
String osname = System.getProperty( " os.name " );
String osversion = System.getProperty( " os.version " );
String java_version = System.getProperty( " java.version " );
writer.print(osname + " " + osversion + " java: " + java_version + "
" );
worksheet.setVisible(true);
desktopPane.revalidate();
// move the carea 1000 times for and back and sample time spend
_timer = new javax.swing.Timer(25, new ActionListener(){
public void actionPerformed(ActionEvent evt){
try{
if(_even == true){
worksheet.repaint();
_even = false;
}
else{
worksheet.repaint();
_even = true;
}
_flickercount++;
if(_flickercount == 2000){
_timer.stop();
writer.print( " count1: " + worksheet.count1 + " mess1: " + worksheet.mess1 + " time spend in paint " + "
" );
writer.print( " count2: " + worksheet.count2 + " mess2: " + worksheet.mess2 + " time spend in paintComponent " + "
" );
}
}
catch (Exception ex){
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
});
_timer.start();
}
public void closefile(){
writer.flush();
writer.close();
}
}
class Page extends JInternalFrame
{
long mess1 = 0;
long mess2 = 0;
int count1 = 0;
int count2 = 0;
protected RuntimeTestFrame _owner = null;
protected PrintWriter _writer = null;
protected Canvas canvas = null; // drawarea of page
protected JScrollPane _sp = null;
public Page(String title,boolean resizable, boolean closable, boolean maximizable, boolean iconifiable,PrintWriter writer,RuntimeTestFrame owner) throws Exception{
super(title,resizable,closable,maximizable,iconifiable);
_writer = writer;
_owner = owner;
JComponent contentPane = (JComponent)this.getContentPane();
canvas = new Canvas(writer,this);
_sp = new JScrollPane(canvas);
contentPane.add(_sp,BorderLayout.CENTER);
canvas.setBackground(Color.WHITE);
canvas.setSize(new Dimension(500,500));
}
public void displayRectangle(Graphics g){
Color boxcolor = new Color(0, 250, 0);
g.setColor(boxcolor);
if(_owner._even == true){
Rectangle r1 = new Rectangle(100, 100, 100, 100);
g.fillRect(r1.x, r1.y, r1.width, r1.height);
}else{
Rectangle r1 = new Rectangle(300, 300, 100, 100);
g.fillRect(r1.x, r1.y, r1.width, r1.height);
}
}
}
class Canvas extends JPanel{
PrintWriter _writer = null;
Page _page = null;
Image offscreen = null;
public Canvas(PrintWriter writer, Page page) throws Exception{
super();
_writer = writer;
_page = page;
}
@Override
public void paint(Graphics g){
long tmess1 = System.currentTimeMillis();
try{
Rectangle r222 = g.getClipBounds();
if(offscreen == null){
int width = getSize().width;
int height = getSize().height;
offscreen = createImage(width, height);
}
Graphics og = offscreen.getGraphics();
og.setClip(r222.x, r222.y, r222.width, r222.height);
super.paint(og); // all drawing into offsreenbuffer
Rectangle clip = g.getClipBounds();
// copy offsreenbuffer to screen in changed rectangle
g.drawImage(offscreen, clip.x, clip.y,clip.x+clip.width,clip.y+clip.height,clip.x, clip.y,clip.x+clip.width,clip.y+clip.height, null);
og.dispose();
}catch (Exception ex){
System.out.println(ex.getMessage());
ex.printStackTrace();
}
tmess1 = System.currentTimeMillis() - tmess1;
_page.mess1 += tmess1;
_page.count1++;
}
@Override
public void paintComponent(Graphics g){
long tmess2 = System.currentTimeMillis();
try{
super.paintComponent(g);
_page.displayRectangle(g);
}catch (Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
tmess2 = System.currentTimeMillis() - tmess2;
_page.mess2 += tmess2;
_page.count2++;
}
}
---------- END SOURCE ----------
SUPPORT :
YES