2

我有一个使用 Netbeans 的 GUI 构建器创建的 JFrame,它只包含一个 JPanel。我创建了一个方法getPanel来获取对此 JPanel 的引用:

public class ShowDrawings extends JFrame {

    public ShowDrawings() {
        initComponents();
    }

    public JPanel getPanel(){
        return panel;
    }

    private JPanel panel;
}

在我的主要功能中,我正在做:

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

但它不画任何东西。请帮我。我看过一些相关的问题,但他们都建议扩展JPanel和覆盖它的paint方法。但我不想那样做。谢谢。

4

2 回答 2

6

我看过一些相关的问题,但他们都建议扩展JPanel和覆盖它的paint方法。但我不想那样做

您不应该覆盖JPanel paint()方法,而是paintComponent(..). 这是最佳实践,如果您想要不会产生异常的代码,应该这样做。在您当前的方法中(如您所见)也这样做会使创建持久性图纸变得更加困难,因为它们会被抹去repaint()

而是扩展JPanel和覆盖paintComponent(Graphics g)不要忘记super.paintComponent(g)在覆盖paintComponent(..)方法中作为第一个调用调用。也不要忘记覆盖getPreferredSize()JPanel以便我们可以返回正确的尺寸并pack()可以被调用JFrame(+1 到 @mKorbels 评论):

这是一些示例代码:

在此处输入图像描述

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);
    }
}
于 2012-12-27T15:28:54.660 回答
3

第一次在repaint()你的ShowDrawings sd框架中,你画过的任何东西 ( sd.getPanel().getGraphics().drawOval(...)) 都会被原始JPanel#paintComponent()方法擦除。

正如安德鲁汤普森所写

不要使用 Component.getGraphics()。相反,子类化并覆盖paint() (AWT) 或paintComponent() (Swing) 方法。

Component.getGraphics() 根本无法工作。Java 使用回调机制来绘制图形。您不应该使用 getGraphics() 将图形信息“推送”到组件中。相反,您应该等到 Java 调用您的paint()/paintComponent()方法。那时您应该向组件提供您想要做的图纸。

如果您只是检查/调试某些内容,您甚至可以执行以下操作:

class Test {
    private JPanel panel = new JPanel() {
        public void paintComponent(Graphics g) {
             g.setColor(Color.BLACK);
             g.drawOval(400, 300, 50, 50);
        }
    };
}
于 2012-12-27T15:12:00.067 回答