AffineTransform.getScaleInstance question  
Author Message
dtown22





PostPosted: 2006-8-22 14:31:00 Top

java-programmer, AffineTransform.getScaleInstance question Hi,

I am using the AffineTransform.getScaleInstance to transform an image
by showing it growing. i.e. something like the following:

while(scale <= 1) {
repaint();
scale += 0.05;
try {
Thread.sleep(25);
}
catch(InterruptedException e) {
e.printStackTrace();
}
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setComposite(AlphaComposite.SrcAtop);
g2.transform(AffineTransform.getScaleInstance(scale, scale));
g2.fill(clipShape);
g2.dispose();
}



the problem is that the image grows large from the top lefthand corner
towards the bottom right hand corner.

What I want is the image to grow from the bottom left hand corner to
the top right hand corner.

I have tried messing with the Scale instance, but I cant seem to figure
it out.

anyone know how to do this? thanks!

 
Knute Johnson





PostPosted: 2006-8-23 3:24:00 Top

java-programmer >> AffineTransform.getScaleInstance question email***@***.com wrote:
> Hi,
>
> I am using the AffineTransform.getScaleInstance to transform an image
> by showing it growing. i.e. something like the following:
>
> while(scale <= 1) {
> repaint();
> scale += 0.05;
> try {
> Thread.sleep(25);
> }
> catch(InterruptedException e) {
> e.printStackTrace();
> }
> }
>
> public void paintComponent(Graphics g) {
> super.paintComponent(g);
> Graphics2D g2 = (Graphics2D) g;
> g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
> RenderingHints.VALUE_ANTIALIAS_ON);
> g2.setComposite(AlphaComposite.SrcAtop);
> g2.transform(AffineTransform.getScaleInstance(scale, scale));
> g2.fill(clipShape);
> g2.dispose();
> }
>
>
>
> the problem is that the image grows large from the top lefthand corner
> towards the bottom right hand corner.
>
> What I want is the image to grow from the bottom left hand corner to
> the top right hand corner.
>
> I have tried messing with the Scale instance, but I cant seem to figure
> it out.
>
> anyone know how to do this? thanks!
>

You need to provide a working example of your problem and a better
explanation of what you really want it to do.

--

Knute Johnson
email s/nospam/knute/
 
dtown22





PostPosted: 2006-8-24 6:45:00 Top

java-programmer >> AffineTransform.getScaleInstance question Ok,

So I have an example...in this example, I only mess with the y-scale,
and the shape gets drawn from the top down to the point where the mouse
is clicked.

I want it to come down the other way, where as i want the shape to
appear as if it is coming upwards.

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;

public class PaintTest extends JPanel {
private double scale = 1.0;
private Shape shape;
private Point startPoint;
float border = 20.0f;
float width = 200 - border;
float height = 200 - border;
public BufferedImage b;


public PaintTest() {
this.setPreferredSize(new Dimension(500, 500));
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
startAnimation(e.getPoint());
}
});
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
if(shape != null) {
Graphics2D g2 = (Graphics2D) g;
g2.scale(1, scale);
g2.fill(shape);
g2.dispose();
}
}

public Shape createShape() {

GeneralPath gp = new GeneralPath();
gp.moveTo(startPoint.x, startPoint.y);
gp.lineTo(startPoint.x, startPoint.y);
gp.lineTo(startPoint.x, startPoint.y - height );
gp.lineTo(startPoint.x + width, startPoint.y - height);
gp.lineTo(startPoint.x + width, startPoint.y );
gp.lineTo(startPoint.x + width/2, startPoint.y);
gp.closePath();
return gp;
}

public void startAnimation(Point p) {
scale = 0.05;
startPoint = p;
shape = createShape();
new Thread(runner).start();
}

private Runnable runner = new Runnable() {
public void run() {
while(scale <= 1) {
repaint();
scale += 0.05;
try {
Thread.sleep(25);
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
};


public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame testFrame = new JFrame("Paint Test");
testFrame.getContentPane().add(new PaintTest());
testFrame.pack();
testFrame.setVisible(true);
}
});
}
}


Thanks!
Knute Johnson wrote:
> email***@***.com wrote:
> > Hi,
> >
> > I am using the AffineTransform.getScaleInstance to transform an image
> > by showing it growing. i.e. something like the following:
> >
> > while(scale <= 1) {
> > repaint();
> > scale += 0.05;
> > try {
> > Thread.sleep(25);
> > }
> > catch(InterruptedException e) {
> > e.printStackTrace();
> > }
> > }
> >
> > public void paintComponent(Graphics g) {
> > super.paintComponent(g);
> > Graphics2D g2 = (Graphics2D) g;
> > g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
> > RenderingHints.VALUE_ANTIALIAS_ON);
> > g2.setComposite(AlphaComposite.SrcAtop);
> > g2.transform(AffineTransform.getScaleInstance(scale, scale));
> > g2.fill(clipShape);
> > g2.dispose();
> > }
> >
> >
> >
> > the problem is that the image grows large from the top lefthand corner
> > towards the bottom right hand corner.
> >
> > What I want is the image to grow from the bottom left hand corner to
> > the top right hand corner.
> >
> > I have tried messing with the Scale instance, but I cant seem to figure
> > it out.
> >
> > anyone know how to do this? thanks!
> >
>
> You need to provide a working example of your problem and a better
> explanation of what you really want it to do.
>
> --
>
> Knute Johnson
> email s/nospam/knute/

 
 
Knute Johnson





PostPosted: 2006-8-24 7:50:00 Top

java-programmer >> AffineTransform.getScaleInstance question email***@***.com wrote:
> Ok,
>
> So I have an example...in this example, I only mess with the y-scale,
> and the shape gets drawn from the top down to the point where the mouse
> is clicked.
>
> I want it to come down the other way, where as i want the shape to
> appear as if it is coming upwards.
>

So do you want to click the mouse at a point and have the shape drawn
from the mouse position up and to the right? Does it need to be scaled
or can you just clip it?

Try changing your paintComponent() to mine below and tell me if that is
what you were trying to get here.

public void paintComponent(Graphics g) {
super.paintComponent(g); // you may not need this line
if(shape != null) {
Graphics2D g2 = (Graphics2D) g;
g2.rotate(Math.PI,250,250);
g2.scale(1, scale);
Shape s = g2.getTransform().createTransformedShape(shape);
g2.fill(s);
g2.dispose(); // you don't need this line
}
}

--

Knute Johnson
email s/nospam/knute/
 
 
dtown22





PostPosted: 2006-8-25 1:07:00 Top

java-programmer >> AffineTransform.getScaleInstance question Hi Knute,

You are correct, I want the shape to be drawn from the mouse position
upwards and to the right, I want to scale the shape so that it seems
like it is growing. My shape is actually a little more complex than a
square, so clipping it would make it look wierd.

I ran your example, and it is close to what i want, I like how it grows
from the bottom up, but I want it to start growing from the point of
the mouse click, rather than the bottom of the frame. I tried playing
with the transfrom, but I didn't have any luck.

Also, why do i not need to dispose g2? is most examples I have seen,
this seems to be the common practice, so I took it as a required step.

thanks!


Knute Johnson wrote:
> email***@***.com wrote:
> > Ok,
> >
> > So I have an example...in this example, I only mess with the y-scale,
> > and the shape gets drawn from the top down to the point where the mouse
> > is clicked.
> >
> > I want it to come down the other way, where as i want the shape to
> > appear as if it is coming upwards.
> >
>
> So do you want to click the mouse at a point and have the shape drawn
> from the mouse position up and to the right? Does it need to be scaled
> or can you just clip it?
>
> Try changing your paintComponent() to mine below and tell me if that is
> what you were trying to get here.
>
> public void paintComponent(Graphics g) {
> super.paintComponent(g); // you may not need this line
> if(shape != null) {
> Graphics2D g2 = (Graphics2D) g;
> g2.rotate(Math.PI,250,250);
> g2.scale(1, scale);
> Shape s = g2.getTransform().createTransformedShape(shape);
> g2.fill(s);
> g2.dispose(); // you don't need this line
> }
> }
>
> --
>
> Knute Johnson
> email s/nospam/knute/

 
 
dtown22





PostPosted: 2006-8-26 5:25:00 Top

java-programmer >> AffineTransform.getScaleInstance question Anyone have any ideas?

thanks!

 
 
Knute Johnson





PostPosted: 2006-8-26 10:48:00 Top

java-programmer >> AffineTransform.getScaleInstance question email***@***.com wrote:
> Hi Knute,
>
> You are correct, I want the shape to be drawn from the mouse position
> upwards and to the right, I want to scale the shape so that it seems
> like it is growing. My shape is actually a little more complex than a
> square, so clipping it would make it look wierd.
>
> I ran your example, and it is close to what i want, I like how it grows
> from the bottom up, but I want it to start growing from the point of
> the mouse click, rather than the bottom of the frame. I tried playing
> with the transfrom, but I didn't have any luck.
>
> Also, why do i not need to dispose g2? is most examples I have seen,
> this seems to be the common practice, so I took it as a required step.
>

This was an intriguing problem and I really didn't know how to solve it
at first. I knew there had to be a simple way and there is. It's a
good thing that I didn't have a lot of work to do the last couple of
days or I'd be in trouble :-).

I think this addresses all of your issues and demonstrates how it works too.

Regarding disposing of the Graphics reference, it isn't necessary in the
paintComponent() method. It is if you create a Graphics from an Image
that you are going to use for active rendering or for some other
purpose. What you need to be careful of though is changing the Graphics
transform and not resetting that when you leave the paintComponent(). I
avoid that by not setting the transform on the Graphics but using the
AffineTransform to modify the Shape. The Graphics.translate() would be
a problem if we weren't resetting it every time that we draw the Shape.

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

public class PaintTest2 extends JPanel implements Runnable {
int x,y;
double scale;
Polygon poly = new Polygon(new int[] {0,10,45,60,56,60},
new int[] {0,30,42,27,12,0},6);
static boolean flip;

public PaintTest2() {
setPreferredSize(new Dimension(400,300));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
x = me.getX();
y = me.getY();
scale = 0.0;
new Thread(PaintTest2.this).start();
}
});
}

public void run() {
while (scale < 1.0) {
scale += 0.1;
repaint();
try { Thread.sleep(40); }
catch (InterruptedException ie) { }
}
}

public void paintComponent(Graphics g2D) {
Graphics2D g = (Graphics2D)g2D;
g.setColor(getBackground());
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(getForeground());

g.translate(x,y); // follow the mouse

AffineTransform at = new AffineTransform();
at.scale(1.0,scale); // scale it
if (flip)
at.scale(1.0,-1.0); // flip it
Shape s = at.createTransformedShape(poly);
g.fill(s);
}

public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JMenuBar mb = new JMenuBar();
f.setJMenuBar(mb);

final JCheckBoxMenuItem cbmi =
new JCheckBoxMenuItem("Flip It!",flip);
cbmi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
flip = cbmi.getState();
}
});
mb.add(cbmi);

PaintTest2 pt2 = new PaintTest2();
f.add(pt2);

f.pack();
f.setVisible(true);
}
};
EventQueue.invokeLater(r);
}
}

--

Knute Johnson
email s/nospam/knute/
 
 
dtown22





PostPosted: 2006-8-29 1:43:00 Top

java-programmer >> AffineTransform.getScaleInstance question Hi Knute,

Thanks for your example. When I first looked at it, it baffled me a bit
why my version wouldn't work, because they seemed so similar. I event
took your version, and commented out the affine transform lines, and
replaced them with:

g.scale(scale,scale);
g.fill(poly);

and everything worked out fine. Then I realized that my problem had to
do with g.translate, and the way i defined my polygon. I was taking the
mouse click point, and using that as my starting point to draw the
polygon, this threw everything off, and i wasnt able to get the desired
affect. So rather, I just changed the starting point of the polygon to:
0,0, and everything works now.

thanks a lot for your help!



Knute Johnson wrote:
> email***@***.com wrote:
> > Hi Knute,
> >
> > You are correct, I want the shape to be drawn from the mouse position
> > upwards and to the right, I want to scale the shape so that it seems
> > like it is growing. My shape is actually a little more complex than a
> > square, so clipping it would make it look wierd.
> >
> > I ran your example, and it is close to what i want, I like how it grows
> > from the bottom up, but I want it to start growing from the point of
> > the mouse click, rather than the bottom of the frame. I tried playing
> > with the transfrom, but I didn't have any luck.
> >
> > Also, why do i not need to dispose g2? is most examples I have seen,
> > this seems to be the common practice, so I took it as a required step.
> >
>
> This was an intriguing problem and I really didn't know how to solve it
> at first. I knew there had to be a simple way and there is. It's a
> good thing that I didn't have a lot of work to do the last couple of
> days or I'd be in trouble :-).
>
> I think this addresses all of your issues and demonstrates how it works too.
>
> Regarding disposing of the Graphics reference, it isn't necessary in the
> paintComponent() method. It is if you create a Graphics from an Image
> that you are going to use for active rendering or for some other
> purpose. What you need to be careful of though is changing the Graphics
> transform and not resetting that when you leave the paintComponent(). I
> avoid that by not setting the transform on the Graphics but using the
> AffineTransform to modify the Shape. The Graphics.translate() would be
> a problem if we weren't resetting it every time that we draw the Shape.
>
> import java.awt.*;
> import java.awt.event.*;
> import java.awt.geom.*;
> import javax.swing.*;
>
> public class PaintTest2 extends JPanel implements Runnable {
> int x,y;
> double scale;
> Polygon poly = new Polygon(new int[] {0,10,45,60,56,60},
> new int[] {0,30,42,27,12,0},6);
> static boolean flip;
>
> public PaintTest2() {
> setPreferredSize(new Dimension(400,300));
> addMouseListener(new MouseAdapter() {
> public void mousePressed(MouseEvent me) {
> x = me.getX();
> y = me.getY();
> scale = 0.0;
> new Thread(PaintTest2.this).start();
> }
> });
> }
>
> public void run() {
> while (scale < 1.0) {
> scale += 0.1;
> repaint();
> try { Thread.sleep(40); }
> catch (InterruptedException ie) { }
> }
> }
>
> public void paintComponent(Graphics g2D) {
> Graphics2D g = (Graphics2D)g2D;
> g.setColor(getBackground());
> g.fillRect(0,0,getWidth(),getHeight());
> g.setColor(getForeground());
>
> g.translate(x,y); // follow the mouse
>
> AffineTransform at = new AffineTransform();
> at.scale(1.0,scale); // scale it
> if (flip)
> at.scale(1.0,-1.0); // flip it
> Shape s = at.createTransformedShape(poly);
> g.fill(s);
> }
>
> public static void main(String[] args) {
> Runnable r = new Runnable() {
> public void run() {
> JFrame f = new JFrame();
> f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
>
> JMenuBar mb = new JMenuBar();
> f.setJMenuBar(mb);
>
> final JCheckBoxMenuItem cbmi =
> new JCheckBoxMenuItem("Flip It!",flip);
> cbmi.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent ae) {
> flip = cbmi.getState();
> }
> });
> mb.add(cbmi);
>
> PaintTest2 pt2 = new PaintTest2();
> f.add(pt2);
>
> f.pack();
> f.setVisible(true);
> }
> };
> EventQueue.invokeLater(r);
> }
> }
>
> --
>
> Knute Johnson
> email s/nospam/knute/

 
 
Knute Johnson





PostPosted: 2006-8-29 1:54:00 Top

java-programmer >> AffineTransform.getScaleInstance question email***@***.com wrote:
> Hi Knute,
>
> Thanks for your example. When I first looked at it, it baffled me a bit
> why my version wouldn't work, because they seemed so similar. I event
> took your version, and commented out the affine transform lines, and
> replaced them with:
>
> g.scale(scale,scale);
> g.fill(poly);
>
> and everything worked out fine. Then I realized that my problem had to
> do with g.translate, and the way i defined my polygon. I was taking the
> mouse click point, and using that as my starting point to draw the
> polygon, this threw everything off, and i wasnt able to get the desired
> affect. So rather, I just changed the starting point of the polygon to:
> 0,0, and everything works now.
>
> thanks a lot for your help!
>

You are welcome. It was a very interesting problem.

--

Knute Johnson
email s/nospam/knute/