проблемы с AffineTransform - PullRequest
       88

проблемы с AffineTransform

3 голосов
/ 15 июля 2011

Здравствуйте, я новичок в affineTransform в Java.Я хочу использовать его, чтобы срезать некоторый графический интерфейс, который я должен использовать позже.Сейчас я просто хотел протестировать пример кода, но я не могу объяснить его вывод.Вот код

    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());
    }


}

Прямоугольник, который я хочу нарисовать на показе класса Left, появляется в центре справа ??Но его приход сместился влево. Кажется, он принимает свои координаты относительно внешней рамки.Если я уберу g2.setTransform(at);, все будет нормально .. Можете ли вы объяснить мне, почему ??

Ответы [ 4 ]

5 голосов
/ 15 июля 2011

Метод setTransform предназначен только для восстановления исходного преобразования Graphics2D после рендеринга. При этом никогда следует применить новое преобразование координат поверх существующего преобразования, поскольку Graphics2D может уже иметь преобразование, необходимое для других целей, таких как рендеринг Качели компонентов. Ваш код иллюстрирует этот момент. Чтобы добавить преобразование координат, используйте методы transform, rotate, scale или shear.

2 голосов
/ 15 июля 2011

Вы, вероятно, рисуете какой-нибудь легкий компонент. Это означает, что у него нет собственной системы координат. Таким образом, он использует координаты своего ближайшего тяжелого веса. система.

Поэтому вам следует объединить преобразование, которое вы хотите сделать, с исходным преобразованием (умножив их.

И после того, как вы закончили рисование, вам (возможно) следует восстановить исходное преобразование.

1 голос
/ 16 июля 2011

Расширяя ответ @ littel , вы можете сравнить текущее преобразование с идентификатором при изменении размера кадра, используя приведенный ниже пример.Обратите внимание, что изменяются только компоненты переноса: dx = 75.0 составляет половину разницы между шириной MyCanvas и Left, в то время как dy включает в себя вертикальное смещение Left и размер зеленой границы.

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);
    }
}
0 голосов
/ 15 июля 2011

Я знаю, где у вас проблемы, вы рисуете на той же графике, что и родитель. "Super.paintComponent (г);"

вы должны попробовать что-то вроде super.repaint ();

...