coder
coder

Reputation: 843

problems with AffineTransform

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

Answers (4)

trashgod
trashgod

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]]

Demo image

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

mre
mre

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

Zemzela
Zemzela

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

Alpedar
Alpedar

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

Related Questions