简体   繁体   English

Graphics2D 未正确绘制,它仅绘制椭圆的一部分

[英]Graphics2D is not drawing correctly, its only drawing part of the oval

I'm trying to draw an oval on a JFrame using Graphics2D, I want it to resize with the window which technically it does, it just not drawing about a 3rd of the oval.我正在尝试使用 Graphics2D 在 JFrame 上绘制一个椭圆,我希望它使用 window 来调整大小,这在技术上是可以做到的,它只是没有绘制大约三分之一的椭圆。 It's definitely something I'm doing wrong, I'm new to the Graphics2D part of Java.这绝对是我做错了,我是 Java 的 Graphics2D 部分的新手。

I wasn't sure if it was my computer so I have tried running my code on a different PC to have it happen again so I'm not sure where I've gone wrong.我不确定这是否是我的计算机,所以我尝试在另一台 PC 上运行我的代码以使其再次发生,所以我不确定我哪里出错了。

import javax.swing.*;
import java.awt.*;

public class ClockViewer {
    public static void main(String[] args) {
        //create frame
        JFrame frame = new JFrame();
        final int Frame_Width = 110;
        final int Frame_Height = 130;

        //set frame attributes
        frame.setSize(Frame_Width, Frame_Height);
        frame.setTitle("A Really Descriptive Title...");
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //get pane attributes
        System.out.println(frame.getContentPane().getWidth());
        System.out.println(frame.getContentPane().getHeight());

        //create ellipse
        EllipseComponent ellipse = new EllipseComponent();

        //add ellipse to frame
        while(frame.getContentPane().getHeight() > 0 && frame.getContentPane().getWidth() > 0) {
            int posX = Math.round(frame.getContentPane().getWidth() / 100) * 20;
            int posY = Math.round(frame.getContentPane().getHeight() / 100) * 20;
            int Width = Math.round(frame.getContentPane().getWidth() / 100) * 80;
            int Height = Math.round(frame.getContentPane().getHeight() / 100) * 80;
            ellipse.setAll(posX, posY, Width, Height);
            frame.add(ellipse);
        }
    }
}

This is the next file:这是下一个文件:

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

public class EllipseComponent extends JComponent {
    //global variables for ellipse drawing
    int posX = 0;
    int posY = 0;
    int Width = 0;
    int Height = 0;

    //getters for getting variables values
    public int getPosX() {
    return this.posX;
    }
    public int getPosY() {
        return this.posY;
    }
    @Override
    public int getWidth() {
        return this.Width;
    }
    @Override
    public int getHeight() {
        return this.Height;
    }

    //setters for setting variable values
    public void setPosX(int newPosX) {
        this.posX = newPosX;
    }
    public void setPosY(int newPosY) {
        this.posY = newPosY;
    }
    public void setWidth(int newWidth) {
        this.Width = newWidth;
    }
    public void setHeight(int newHeight) {
        this.Height = newHeight;
    }

    //setter for all variables
    public void setAll(int newPosX, int newPosY, int newWidth, int newHeight) {
        this.posX = newPosX;
        this.posY = newPosY;
        this.Width = newWidth;
        this.Height = newHeight;
    }

    //paint ellipse using graphics
    @Override
    public void paint(Graphics g) {
        Graphics g2 = (Graphics2D) g;
        g2.drawOval(posX, posY, Width, Height);
    }
}

Thanks for any help you all can provide me ^^谢谢大家能给我的帮助^^

Edit: I'm getting these errors if it helps:编辑:如果有帮助,我会收到这些错误:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: No such child: 0

at java.awt.Container.getComponent(Container.java:336)

at javax.swing.JComponent.rectangleIsObscured(JComponent.java:4390)

at javax.swing.JComponent.paint(JComponent.java:1054)

at javax.swing.JComponent.paintToOffscreen(JComponent.java:5210)

at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)

at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)

at javax.swing.RepaintManager.paint(RepaintManager.java:1272)

at javax.swing.JComponent._paintImmediately(JComponent.java:5158)

at javax.swing.JComponent.paintImmediately(JComponent.java:4969)

at javax.swing.RepaintManager$4.run(RepaintManager.java:831)

at javax.swing.RepaintManager$4.run(RepaintManager.java:814)

at java.security.AccessController.doPrivileged(Native Method)

at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)

at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)

at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)

at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)

at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)

at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)

at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)

at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)

at java.awt.EventQueue.access$500(EventQueue.java:97)

at java.awt.EventQueue$3.run(EventQueue.java:709)

at java.awt.EventQueue$3.run(EventQueue.java:703)

at java.security.AccessController.doPrivileged(Native Method)

at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)

at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)

at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)

at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)

at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

I am not getting the error you get.我没有得到你得到的错误。 However, this is not the right way to do custom painting in Swing.但是,这不是在 Swing 中进行自定义绘画的正确方法。 I suggest you to take a look on how to perform custom painting .我建议你看看如何进行自定义绘画 Long story short though, this thing you are trying with the while condition will not work.长话短说,你在while条件下尝试的这个东西是行不通的。 Instead, let the component to be painted according to its parent size and coordinates without having to set them explicit:相反,让组件根据其父大小和坐标进行绘制,而不必显式设置它们:

/**
 * @Overide paint method was a thing in AWT.
 * In Swing you must override paintComponent (and call super.paintComponent())
 * in order to respect the paint chain.
 * 
 */
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (getParent() != null) { //Paint according to parent
        Graphics g2 = (Graphics2D) g;
        //Calculations
        int posX = Math.round(getParent().getWidth() / 100) * 20;
        int posY = Math.round(getParent().getHeight() / 100) * 20;
        int Width = Math.round(getParent().getWidth() / 100) * 80;
        int Height = Math.round(getParent().getHeight() / 100) * 80;
        g2.drawOval(posX, posY, Width, Height);
    }
}

Another not necessary thing you did is this:你做的另一件不必要的事情是:

@Override
public int getWidth() {
    return this.Width;
}

Overriding getWidth and getSize of a component would not lead you anywhere.覆盖组件的getWidthgetSize不会带您到任何地方。

Other useful links I recommend you to read are the Initial Threads and Why shouldn't I call setVisible(true) before adding components?我建议您阅读的其他有用链接是Initial Threads以及为什么我不应该在添加组件之前调用 setVisible(true)?

The full example:完整的例子:

public class ClockViewer {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(()->{
            // create frame
            JFrame frame = new JFrame();
            final int Frame_Width = 110;
            final int Frame_Height = 130;

            // set frame attributes
            frame.setSize(Frame_Width, Frame_Height);
            frame.setTitle("A Really Descriptive Title...");

            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            // get pane attributes
            System.out.println(frame.getContentPane().getWidth());
            System.out.println(frame.getContentPane().getHeight());

            // create ellipse
            JComponent ellipse = new JComponent() {
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    if (getParent() != null) { //Paint according to parent
                        Graphics g2 = (Graphics2D) g;
                        //Calculations
                        int posX = Math.round(getParent().getWidth() / 100) * 20;
                        int posY = Math.round(getParent().getHeight() / 100) * 20;
                        int Width = Math.round(getParent().getWidth() / 100) * 80;
                        int Height = Math.round(getParent().getHeight() / 100) * 80;
                        g2.drawOval(posX, posY, Width, Height);
                    }
                }
            };
            frame.add(ellipse);
            frame.setVisible(true);
        });

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM