【问题标题】:Can not draw oval on a JPanel无法在 JPanel 上绘制椭圆
【发布时间】:2012-12-12 22:58:39
【问题描述】:

我有一个使用 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 方法。但我不想那样做。 谢谢。

【问题讨论】:

  • 如果您使用的是Netbeans的GUI builder,应该不会有任何问题。我已经使用过很多次了。能否请您发布完整代码?

标签: java swing jpanel java-2d paintcomponent


【解决方案1】:

当你第一次repaint()你的ShowDrawings sd框架时,你画的任何东西(sd.getPanel().getGraphics().drawOval(...))都会被原来的JPanel#paintComponent()方法删除。

作为Andrew Thompson has written:

不要使用 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);
        }
    };
}

【讨论】:

  • 然后必须为 JPanel 覆盖 PreferredSize :-)
【解决方案2】:

我看过一些相关的问题,但它们都在暗示 扩展 JPanel 并覆盖其 paint 方法。但我不想 这样做

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

宁可扩展JPanel 并覆盖paintComponent(Graphics g),不要忘记调用super.paintComponent(g) 作为覆盖paintComponent(..) 方法中的第一个调用。也不要忘记覆盖JPanelgetPreferredSize(),以便我们可以返回正确的尺寸,并且可以在JFrame 上调用pack()(+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);
    }
}

【讨论】:

  • 对于圆形和其他椭圆,您可能还需要g.setRenderingHint( RenderingHints. KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE),请参阅stackoverflow.com/a/31221395/1143274
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-08
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
相关资源
最近更新 更多