简体   繁体   English

为什么不能使用“图形”在我的JPanel上绘画?

[英]Why can't I paint onto my JPanel using Graphics?

I keep running into this problem when I try to paint to my extended version of a JPanel. 当我尝试绘制扩展版的JPanel时,我一直遇到这个问题。 Every time, I eventually find a way to get it to work. 每次,我最终都找到一种使其工作的方法。 But I want to know exactly why it is that painting to a JPanel in this way doesn't work? 但是我想确切地知道为什么以这种方式向JPanel绘画不起作用?

public class MyPanel extends JPanel {

public MyPanel(){
    init();
}

public void init(){
    JFrame frame = new JFrame("");
    frame.add(this);
    this.setPreferredSize(new Dimension(100,100));
    this.setBackground(Color.RED);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);

    Graphics g = this.getGraphics();
    g.setColor(Color.BLUE);
    g.fillRect(0, 0, 50, 50);
}

public static void main(String[] args) {
    new MyPanel();
}

}

When I run this code, I see the red background I would expect from setBackground(Color.RED), but I don't see the blue rectangle that I painted using the Graphics object. 当我运行此代码时,我看到了setBackground(Color.RED)所期望的红色背景,但是看不到使用Graphics对象绘制的蓝色矩形。 It doesn't show up, even if I call repaint() on the last line in init(). 即使我在init()的最后一行调用repaint(),它也不会显示。

What is wrong with this code, so I can avoid it in the future? 该代码有什么问题,所以将来可以避免吗?

Why can't I paint onto my JPanel using Graphics? 为什么不能使用“图形”在我的JPanel上绘画?

Because this is not the right way to do it. 因为这不是正确的方法。 You should override the paintComponent method: 您应该重写paintComponent方法:

public class MyPanel extends JPanel {

    public MyPanel(){
        init();
    }

    public void init(){
        JFrame frame = new JFrame("");
        frame.add(this);
        this.setPreferredSize(new Dimension(100,100));
        this.setBackground(Color.RED);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

    }

    public static void main(String[] args) {
        new MyPanel();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, 50, 50);
    }
}

If you don't do so, your drawing will be visible for just one moment, and then it will disappear. 如果不这样做,您的图形将仅显示一会儿,然后消失。 This way, whenever you call the repaint method (or whenever the application gets repainted itself), that method will be called and your rectangle will be filled. 这样,无论何时调用repaint方法(或应用程序自身重新绘制),该方法都会被调用,并且矩形将被填充。

Custom painting in Swing is typically done by overriding the paintComponent Method of classes that extend from JComponent Swing中的自定义绘制通常是通过重写从JComponent扩展的类的paintComponent方法来完成的

See Performin a Custom Painting for details 有关详细信息,请参见在自定义绘画中执行

Basically, the problem is, painting in Swing is destructive process. 基本上,问题是,Swing中的绘画是破坏性的过程。 Each time a paint cycle occurs, you are expected to clean and regenerate the output. 每次发生油漆循环时,都应清洁并重新生成输出。 getGraphics is unreliable. getGraphics不可靠。 It can return null and anything you paint using it, will be over painted on the next paint cycle 它可以返回null,并且您使用它paint任何内容都将在下一个绘制周期中被过度绘制

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

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