【问题标题】:problems with AffineTransform仿射变换的问题
【发布时间】:2011-07-15 10:35:54
【问题描述】:

您好,我是 java 中 affineTransform 的新手。我想用它来剪切一些我以后必须使用的 GUI。 现在我只想测试一个示例代码,但我无法解释它的输出。 这是代码

    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类show中画的矩形出现在中间吧??但是它的到来向左移动了。它似乎是相对于外部框架的坐标。如果我删除 g2.setTransform(at); 就正常了。你能解释一下为什么吗??

【问题讨论】:

  • 你怎么做 g2.getWidth() ??
  • sscce+1。

标签: java swing java-2d affinetransform


【解决方案1】:

setTransform 方法仅用于在渲染后恢复原始的Graphics2D 变换。话虽如此,您应该永远在现有变换之上应用新的坐标变换,因为Graphics2D 可能已经具有其他用途所需的变换,例如作为渲染 Swing 组件。您的代码说明了这一点。要添加坐标变换,请使用transformrotatescaleshear 方法。

【讨论】:

  • 你必须有大/大的粉丝俱乐部,没有别的(把你所有的帖子放在一起)+1
  • 如果有人在没有书面有价值的理由的情况下对任何帖子投了反对票,那么为什么要详细说明这一点,只是她/他的分歧没有效果,仅此而已,如果她/他想要,为什么要问这个那可能会写为什么:-)
  • 你的脑袋一定很热,为什么会发火,完全忽略这一点,不是你的真实身份,专业社区 == 很多人都在那里玩,比如我的人 :-)
  • @little:我既不是反对者也不是版主;我在 11 小时前投了赞成票。看起来这里的所有答案都被系统地否决了,还有你的大约 30 个。您可以audit您的帐户以查看更多信息。如果自动 fraud detection mechanism 没有捕捉到它,您可以标记它以引起版主注意。我都受到了打击。
【解决方案2】:

您可能正在绘制一些轻量级组件。这意味着它没有自己的坐标系。所以它使用它最接近的重量级父坐标。系统。

因此,您应该将想要进行的转换与原始转换结合起来(通过将它们相乘。

在你画完之后,你(也许)应该恢复原来的变换。

【讨论】:

  • 我看不出哪里有混合轻量级和重量级组件的地方。你在说什么?
  • 要绘制任何东西,必须有硬件组件。挥杆中的很多东西都是LW。 JFrame 是 HW 的,Panel 是 LW 的,并且居中,所以它向侧面移动,这是通过仿射变换和裁剪完成的。
【解决方案3】:

在@littel 的answer 上展开,您可以将当前的transform 与使用下面的示例调整框架大小时的标识进行比较。请注意,只有平移分量不同:dx = 75.0MyCanvasLeft 宽度差的一半,而dy 包括Left 的垂直偏移量和绿色边框的大小。

身份:AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]] 身份:AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]] 当前:AffineTransform[[1.0, 0.0, 75.0], [0.0, 1.0, 201.0]] 当前: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);
    }
}

【讨论】:

    【解决方案4】:

    我知道你的问题出在哪里,你绘制的图形与父级相同。 “super.paintComponent(g);”

    你应该尝试类似 super.repaint();

    【讨论】:

    • -1,在paintComponent() 方法中调用repaint() 是不行的。
    • @little bunny foo foo 在给出 -1 之前,给出建设性的论点。你很粗鲁。
    • 简单 - 因为您最终会不断调用paintComponent() 直到程序终止。为了将来参考,请不要声称您“知道”问题出在哪里,而您显然不知道。
    • 我做到了,而且确实做到了。顺便说一句,您是否浏览了我所有的答案/问题并否决了它们?
    • 无限循环——说得够多了
    猜你喜欢
    • 2010-12-17
    • 2011-08-15
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多