Glitches with painting a component into an image, with AffineTransform

I made the test program below. I want to create an image out of a component, that has some random lines painted on it. Running the program and pushing the button will create a file "out.png".

The component has original size (4000,4000). I try to scale it down with AffineTransform, applied into the image's Graphics object.The lines do not appear correctly. The seem just like when you have animage with lines, and produce a quick thumbnail out of it. But I don't understand why this is happening. I actually draw lines with an AffineTransform, so I would expect that a line will be drawn in merely different coordinates.

Why the lines fail to appear correctly?

And a side issue. When I scroll, the component fails to repaint appropriately, I'm seeing visual remains of previous paints. Why does this happen?

Here is the code, run under 1.6:

//ImageTest.java

import java.awt.BorderLayout;

import java.awt.Component;

import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import java.util.Random;

import javax.imageio.ImageIO;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

/**

*

* @author andreou

*/

publicclass ImageTestextends JFrame{

privatefinal Component c;

public ImageTest(){

c =new MyComponent();

add(new JScrollPane(c));

JButton button =new JButton("save");

button.addActionListener(new ActionListener(){

publicvoid actionPerformed(ActionEvent e){

save();

}

});

add(button, BorderLayout.NORTH);

}

privatevoid save(){

BufferedImage bi = (BufferedImage)c.createImage(c.getWidth(), c.getHeight());

Graphics2D g = (Graphics2D)bi.getGraphics();

double w = 800;

double h = 800;

g.setTransform(AffineTransform.getScaleInstance(w / c.getWidth(), h / c.getHeight()));

c.paint(g);

g.dispose();

try{

ImageIO.write(bi,"png",new File("out.png"));

}catch (IOException ex){

ex.printStackTrace();

}

}

publicstaticvoid main(String[] args){

JFrame f =new ImageTest();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.setSize(400, 400);

f.setLocationRelativeTo(null);

f.setVisible(true);

}

}

class MyComponentextends JPanel{

privatefinal Random random =new Random();

{

setPreferredSize(new Dimension(4000, 4000));

}

publicvoid paintComponent(Graphics g){

Random r =new Random(0);

for (int i = 0; i < 1000; i++){

g.drawLine(nextX(r), nextY(r), nextX(r), nextY(r));

}

}

privateint nextX(Random random){

return random.nextInt(getWidth());

}

privateint nextY(Random random){

return random.nextInt(getHeight());

}

}

Thanks a lot for any help

[6045 byte] By [ounosa] at [2007-11-27 9:06:47]
# 1
To fix the repaint issue just add super.paintComponent(g); at the beginning of the paintComponent function of MyComponent.When you set scaling on Graphics2D using AffineTransform it also changes the stroke size.
Rodney_McKaya at 2007-7-12 21:42:41 > top of Java-index,Desktop,Core GUI APIs...
# 2
Amazing. I thought paintComponent did not override needed code - only paint did. Nice source of bugs...Thanks. I'll try using a bigger stroke, I think it will work.
ounosa at 2007-7-12 21:42:41 > top of Java-index,Desktop,Core GUI APIs...
# 3
Thanks! It worked!
ounosa at 2007-7-12 21:42:41 > top of Java-index,Desktop,Core GUI APIs...