简体   繁体   中英

repaint() method in JFrame or Jpanel?

I'm new to Java and just started learning GUI components. So, I was reading Headfirst Java and there is this code explaining paintcomponent method of JPanel . It is just to change color of oval whenever user clicks on 'change colors' button. -

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class SimpleGui3C implements ActionListener {

    JFrame frame;

    public static void main(String[] args) {
        SimpleGui3C gui = new SimpleGui3C();
        gui.go();
    }

    public void go() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton button = new JButton("Change colors");
        button.addActionListener(this);

        MyDrawPanel drawPanel = new MyDrawPanel();

        frame.getContentPane().add(BorderLayout.SOUTH, button);
        frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
        frame.setSize(500,500);
        frame.setVisible(true);
    }

    public void actionPerformed(ActionEvent event) {
        frame.repaint();
    }
}

MyDrawPanel Class -

import javax.swing.*;
import java.awt.*;

class MyDrawPanel extends JPanel {

    public void paintComponent(Graphics g) {

        Graphics2D g2d = (Graphics2D) g;

//      GradientPaint gradient = new GradientPaint(70,70,Color.blue,150,150,Color.orange);

        int red = (int) (Math.random() * 255);
        int green = (int) (Math.random() * 255);
        int blue = (int) (Math.random() * 255);
        Color startColor = new Color(red, green, blue);

        red = (int) (Math.random() * 255);
        green = (int) (Math.random() * 255);
        blue = (int) (Math.random() * 255);
        Color endColor = new Color(red, green, blue);

        GradientPaint gradient = new GradientPaint(70,70,startColor,150,150,endColor);

        g2d.setPaint(gradient);
        g2d.fillOval(70,70,100,100);
    }
}

I got everything out of this example except for the part where we call repaint() method.

In the book, it was mentioned that just override the paintcomponent method of JPanel and when you call repaint() , it will call paintcomponent to render the content (since we do not call paintcomponent directly).

Now, I created MyDrawPanel class by extending JPanel and overridden its paintComponent method. Now when we put drawPanel widget on frame and then on mouse-click, repint() method is being called. But this repaint() method is being called using frame - an object of JFrame . As per my basic java understanding, if I'm calling a method using an object, that method has to be in that class or in some Super class. I don't see how calling repaint() on frame will trigger paint component of MyDrawPanel . I did some digging to see if JFrame and JPanel share the same hierarchy and here is what I found :

object --> component (has repaint method) --> container (has paintcomponent method)-->

        `jcomponent` --> `jpanel`

        `window` --> `frame` --> `jframe`

So I thought that since JFrame and JPanel both get paintComponent and repaint methods, may be I can extend Jframe to create MyDrawPanel instead of Jpanel and it should work fine. But it doesn't. It compiles fine but throws runtime exception.

It's really frustrating. May be I'm not getting GUI concepts or my basics are still weak. Please let me know if I'm missing something really silly here.

Let's start with paintComponent should really call super.paintComponent before performing any custom painting

Then move onto you really should read Painting in AWT and Swing and Performing Custom Painting for a better understanding of how painting works in Swing. repaint doesn't call paintComponent directly, it asks the RepaintManager to schedule a paint event on the event queue, which is, at some point in the future, processed by the Event Dispatching Thread, which then process the paint event based on the needs of the container

So I thought that since JFrame and JComponent both get paintComponent

No, they don't. JFrame (and it's parent class) do not have a paintComponent method

may be I can extend Jframe to create MyDrawPanel instead of Jpanel and it should work fine"

No, you shouldn't, apart from JFrame not having a paintComponent , there is a lot more going on which can interfere with any custom painting your might try and perform on a JFrame and you should continue structuring your code the way it is

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