Reputation: 843
Hello I am new to affineTransform
in java. I want to use it to shear some GUI I have to use later.
For now I just wanted to test a sample code but i cannot explain its output.
Here is the code
package main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainClass{
public static void main(String[] args) {
JFrame jf = new JFrame("Demo");
jf.getContentPane().add(new MyCanvas());
jf.setSize(600, 600);
jf.setVisible(true);
}
}
class Left extends JPanel {
Left(){
setPreferredSize(new Dimension(450,450));
setBorder(BorderFactory.createLineBorder(Color.green));
setBackground(Color.gray);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = new AffineTransform();
g2.setTransform(at);
g2.drawRect(getWidth()/2 - 10, getHeight()/2 - 10, 20, 20);
}
}
class MyCanvas extends JPanel {
MyCanvas()
{
setBorder(BorderFactory.createLineBorder(Color.red));
setLayout(new FlowLayout(FlowLayout.CENTER));
add(new Left());
}
}
The rectangle I want to draw in the Left
class show appear in the center right?? But its coming shifted to left.. It seems its taking its coordinates with relative to the outer frame. If I remove the g2.setTransform(at);
it comes normal.. Can you explain me why??
Upvotes: 3
Views: 4587
Reputation: 205765
Expanding on @littel's answer, you can compare the current transform to the identity as the frame is resized using the example below. Note that only the translational components vary: dx = 75.0
is half the difference between the width of MyCanvas
and Left
, while dy
includes the vertical offset of Left
and the size of the green border.
Identity: AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]] Identity: AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]] Current: AffineTransform[[1.0, 0.0, 75.0], [0.0, 1.0, 201.0]] Current: AffineTransform[[1.0, 0.0, 75.0], [0.0, 1.0, 1.0]]
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.geom.AffineTransform;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainClass {
public static void main(String[] args) {
JFrame jf = new JFrame("Demo");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(new GridLayout(0, 1));
jf.add(new MyCanvas());
jf.add(new MyCanvas());
jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
}
class MyCanvas extends JPanel {
MyCanvas() {
setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
setPreferredSize(new Dimension(600, 200));
setBorder(BorderFactory.createLineBorder(Color.red));
add(new Left(), BorderLayout.CENTER);
}
}
class Left extends JPanel {
Left() {
setPreferredSize(new Dimension(450, 100));
setBorder(BorderFactory.createLineBorder(Color.green));
setBackground(Color.gray);
System.out.println("Identity: " + new AffineTransform());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
System.out.println("Current: " + g2.getTransform());
g2.drawRect(getWidth() / 2 - 10, getHeight() / 2 - 10, 20, 20);
}
}
Upvotes: 2
Reputation: 44240
The setTransform
method is intended only for restoring the original Graphics2D
transform after rendering. That being said, you should never apply a new coordinate transform on top of an existing transform because the Graphics2D
might already have a transform that is needed for other purposes, such as rendering Swing components. Your code exemplifies this point. To add a coordinate transform, use the transform
, rotate
, scale
, or shear
methods.
Upvotes: 7
Reputation: 3080
I know where is you problem, you draw on same graphics as parent. "super.paintComponent(g);"
you should try something like super.repaint();
Upvotes: -3
Reputation: 1344
You are probubly drawing some lightweight component. That means it does not have its own coordinate system. So it use its closest heavy weight parrent's coord. system.
Therefore you should combine transformation you want to do with original transformation (by multiplying them.
And after you are done drawing, you (maybe) should restore original transformation.
Upvotes: 3