Search code examples
javaswingscalejava-2d

Java bug? Why draws rectangle instead of ellipse?


The code below draws rectangle and 2 ellipses.

enter image description here

While should draw 3 ellipses.

My OS is Windows 7 prof 64 bit

My Java is 1.6 x86 also 1.7 x64 tested.

Why?

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

            }
        });

    }

}

Solution

  • I copy/pasted your code and it drew the 2 ellipses you wrote about, the only change I made was to replace your MigLayout by null, set the frame and panel dimensions by hand and remove the frame.pack() invocation:

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

    enter image description here

    Update: Could reproduce the problem using the Oracle JDK (java version "1.8.0-ea") instead of the OpenJDK. Got the diamond shape, as pointed out in another answers, the scale factor is the root cause of the shape degenaration, don't know if that should be the appropiate behaviour though, so, there must be a bug in one these JRE's. The following test program works fine for both JRE's:

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