简体   繁体   English

不能在JPanel上绘制椭圆形

[英]Can not draw oval on a JPanel

I have a JFrame created with GUI builder of Netbeans, which contains a JPanel only. 我有一个使用Netbeans的GUI构建器创建的JFrame,它只包含一个JPanel。 I have created a method getPanel for getting a reference to this JPanel: 我创建了一个方法getPanel来获取对这个JPanel的引用:

public class ShowDrawings extends JFrame {

    public ShowDrawings() {
        initComponents();
    }

    public JPanel getPanel(){
        return panel;
    }

    private JPanel panel;
}

In my main function I am doing: 在我的主要功能中我正在做:

public class Main {
    public static void main(String[] args){
        ShowDrawings sd = new ShowDrawings();
        sd.setSize(800, 600);
        Graphics g = sd.getPanel().getGraphics();
        g.setColor(Color.BLACK);
        g.drawOval(400, 300, 50, 50);
        sd.getPanel().paint(g);
        sd.repaint();
        sd.setVisible(true);
    }
}

But it does not draw anything. 但它没有任何吸引力。 Please help me. 请帮我。 I have looked some related questions but they are all suggesting extending JPanel and overriding its paint method. 我看了一些相关的问题,但他们都建议扩展JPanel并覆盖其paint方法。 But I did not want to do that way. 但我不想这样做。 Thanks. 谢谢。

I have looked some related questions but they are all suggesting extending JPanel and overriding its paint method. 我看了一些相关的问题,但他们都建议扩展JPanel并覆盖其paint方法。 But I did not want to do that way 但我不想这样做

You should not override JPanel paint() method, rather paintComponent(..) . 您不应该覆盖JPanel paint()方法,而应该覆盖paintComponent(..) This is best practice and should be done if you want code that will not produce anomalies. 这是最佳实践,如果您希望代码不会产生异常,则应该这样做。 Also doing it in your current approach (as you have seen) makes creating persistent drawings a lot harder as they are wiped away on repaint() 在你当前的方法中做到这一点(正如你所看到的那样)使得创建持久性绘图变得更加困难,因为它们在repaint()消失了repaint()

Rather extend JPanel and override paintComponent(Graphics g) not forgetting to call super.paintComponent(g) as first call in overridden paintComponent(..) method. 而是扩展JPanel并覆盖paintComponent(Graphics g)不要忘记在重写的paintComponent(..)方法中调用super.paintComponent(g)作为第一次调用。 Also dont forget to override getPreferredSize() of JPanel so that we can return correct dimensions and pack() may be called on JFrame (+1 to @mKorbels comment): 另外不要忘记覆盖JPanel getPreferredSize() ,以便我们可以返回正确的维度,并且可以在JFrame上调用pack() (+1到@mKorbels注释):

Here is some example code: 这是一些示例代码:

在此输入图像描述

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    public Test() {
        initComponents();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }

    private void initComponents() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel testPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics grphcs) {
                super.paintComponent(grphcs);

                Graphics2D g2d = (Graphics2D) grphcs;

                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                g2d.setColor(Color.GREEN);
                //g2d.drawOval(10,10,100,100);//I like fill :P
                g2d.fillOval(10,10,100,100);

            }

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(150, 150);
            }
        };

        frame.add(testPanel);

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

The first time you repaint() your ShowDrawings sd frame anything you've painted like this ( sd.getPanel().getGraphics().drawOval(...) ) would be erased by the original JPanel#paintComponent() method. 第一次repaint()你的ShowDrawings sd框架时,你所绘制的任何东西( sd.getPanel().getGraphics().drawOval(...) )都将被原始的JPanel#paintComponent()方法擦除。

As Andrew Thompson has written : 正如安德鲁汤普森所写

Do not use Component.getGraphics(). 不要使用Component.getGraphics()。 Instead, subclass and override the paint() (AWT), or paintComponent() (Swing) method. 相反,子类和覆盖paint()(AWT)或paintComponent()(Swing)方法。

Component.getGraphics() simply can't work. Component.getGraphics()根本无法工作。 Java uses a callback mechanism for drawing graphics. Java使用回调机制绘制图形。 You are not supposed to "push" graphics information into a component using getGraphics(). 您不应该使用getGraphics()将图形信息“推送”到组件中。 Instead you are supposed to wait until Java calls your paint()/paintComponent() method. 相反,你应该等到Java调用你的paint()/ paintComponent()方法。 At that moment you are supposed to provide the Component with the drawings you would like to do. 那时你应该为Component提供你想要做的图纸。

If you're just checking/debugging something you could even do something like this: 如果您只是检查/调试某些内容,您甚至可以执行以下操作:

class Test {
    private JPanel panel = new JPanel() {
        public void paintComponent(Graphics g) {
             g.setColor(Color.BLACK);
             g.drawOval(400, 300, 50, 50);
        }
    };
}

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

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