简体   繁体   中英

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. 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?

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. It doesn't show up, even if I call repaint() on the last line in init().

What is wrong with this code, so I can avoid it in the future?

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

Because this is not the right way to do it. You should override the paintComponent method:

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.

Custom painting in Swing is typically done by overriding the paintComponent Method of classes that extend from JComponent

See Performin a Custom Painting for details

Basically, the problem is, painting in Swing is destructive process. Each time a paint cycle occurs, you are expected to clean and regenerate the output. getGraphics is unreliable. It can return null and anything you paint using it, will be over painted on the next paint cycle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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