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.