4

下面的代码绘制矩形和 2 个椭圆。

在此处输入图像描述

虽然应该画3个椭圆。

我的操作系统是 Windows 7 prof 64 位

我的 Java 是 1.6 x86 也经过 1.7 x64 测试。

为什么?

package tests;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import net.miginfocom.swing.MigLayout;

public class AntialiacingScaleTester {

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                JPanel circlePanel = new JPanel() {
                    @Override
                    public void paintComponent(Graphics g) {

                        super.paintComponent(g);

                        Graphics2D g2d = (Graphics2D)g;
                        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                        g2d.setColor(Color.RED);
                        g2d.setStroke(new BasicStroke(1));
                        //g2d.drawOval(0, 0, 200, 200);
                        g2d.draw(new Ellipse2D.Double(0, 0, 200, 200));

                        AffineTransform old = g2d.getTransform();

                        g2d.setColor(Color.GREEN);
                        g2d.scale(1000, 1000);
                        g2d.setStroke(new BasicStroke(0.001f));
                        g2d.draw(new Ellipse2D.Double(0, 0, 0.225, 0.225));

                        g2d.setColor(Color.BLUE);
                        g2d.scale(10, 10);
                        g2d.setStroke(new BasicStroke(0.001f));
                        g2d.draw(new Ellipse2D.Double(0, 0, 0.025, 0.025));

                        g2d.setTransform(old);

                    }
                };

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


                //frame.setLayout(new MigLayout("fill"));
                //frame.add(circlePanel, "w 300, h 300, grow");

                //frame.add(circlePanel);

                frame.setLayout(null);
                circlePanel.setBounds(new Rectangle(0, 0, 300, 300));
                frame.add(circlePanel);

                frame.setBounds(0, 0, 350, 300);

                //frame.pack();
                frame.setVisible(true);

            }
        });

    }

}
4

2 回答 2

2

我复制/粘贴了您的代码,它绘制了您写的 2 个省略号,我所做的唯一更改是替换您MigLayout的 by null,手动设置框架和面板尺寸并删除frame.pack()调用:

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
        JPanel circlePanel = new JPanel() {
            @Override
            public void paint(Graphics g) {

                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                g2d.setStroke(new BasicStroke(1));
                //g2d.drawOval(0, 0, 200, 200);
                g2d.draw(new Ellipse2D.Double(0, 0, 200, 200));

                AffineTransform old = g2d.getTransform();

                g2d.scale(10000, 10000);
                g2d.setStroke(new BasicStroke(0.001f));
                g2d.draw(new Ellipse2D.Double(0, 0, 0.025, 0.025));

                g2d.setTransform(old);

            }
        };

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setLayout(null);
        circlePanel.setBounds(new Rectangle(0, 0, 300, 300));
        frame.add(circlePanel);

        frame.setBounds(0, 0, 350, 300);

        //frame.pack();
        frame.setVisible(true);
    }
}

在此处输入图像描述

更新: 可以使用 Oracle JDK(java 版本“1.8.0-ea”)而不是 OpenJDK 重现该问题。得到了菱形,正如另一个答案中指出的那样,比例因子是形状退化的根本原因,虽然不知道这是否应该是适当的行为,所以这些 JRE 中一定有一个错误。以下测试程序适用于两个 JRE:

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
        JPanel circlePanel = new JPanel() {
            @Override
            public void paint(Graphics g) {

                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                g2d.setStroke(new BasicStroke(1));
                //g2d.drawOval(0, 0, 200, 200);
                g2d.draw(new Ellipse2D.Double(0, 0, 200, 200));

                AffineTransform old = g2d.getTransform();

                g2d.scale(10, 10);
                g2d.setStroke(new BasicStroke(1.0f));
                g2d.draw(new Ellipse2D.Double(0, 0, 25.0, 25.0));

                g2d.setTransform(old);

            }
        };

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setLayout(null);
        circlePanel.setBounds(new Rectangle(0, 0, 300, 300));
        frame.add(circlePanel);

        frame.setBounds(0, 0, 350, 300);

        //frame.pack();
        frame.setVisible(true);
    }
}
于 2012-12-24T01:51:45.160 回答
1

在 Eclipse 中的 Java 7、Windows 7 上复制,删除了布局管理器。

我的感觉是,这是由于小浮点值的高缩放和不准确性相结合,减少了生成的点数。

如果您替换值介于 0.0363 和 0.0362 之间,则渲染 API 会中断。它不再生成弧,而是生成正方形。

解决方法是停止将巨大的缩放与微小的对象结合起来。缩小并增加尺寸。

于 2012-12-25T23:18:22.380 回答