Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Swing - JPanel vs JComponent

I'm playing around with Java Swing and i'm really confused when comes to JPanel vs JComponent. According to CoreJava Vol 1 (cay horstmann):

Instead of extending JComponent, some programmers prefer to extend the JPanel class. A JPanel is intended to be a container that can contain other components, but it is also possible to paint on it. There is just one difference. A panel is opaque, which means that it is responsible for painting all pixels within its bounds. The easiest way to achieve that is to paint the panel with the background color, by calling super.paintComponent in the paintComponent method of each panel subclass:

class NotHelloWorldPanel extends JPanel {
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    . . . // code for drawing will go here
  }
}

I know what opaque is. What does he meant by 'A panel is opaque .. responsible for painting all pixels within its bound'? If I read it correctly it says a panel will paint its own areas within its boundaries .. Doesn't JComponent does that too?

Bottom line is I couldn't see the difference between JPanel and JComponent. Is there a simple examples where I can REALLY see it?

Any help is appreciated

like image 588
yapkm01 Avatar asked Oct 01 '13 17:10

yapkm01


1 Answers

A JComponent is not required to paint all pixels in it's bound. It may leave some transparent so you can see components behind it.

A JPanel is required to paint all pixels.

Of course if you don't call the super.paintComponent(..) method in either case, they're going to be more or less equivilent, as you then throw out the guarentee that the JPanel will paint the entire panel.

In short, the difference lies in the methods that already exist(namely paint component).

EDIT:

Example of a ball class implemented with a JComponent would look something like this:

(This would not work with a JPanel, as the JPanel is opaque, and the ball would have a square background. You could not call super.paintComponent, but as a general rule you always should, or you break what the component really is. If I pass a JPanel into something, they expect it to be a JPanel, not a JPanel hacked to behave like a JComponent)

public class Ball extends JComponent
{
    public Ball(int x, int y, int diameter)
    {
        super();
        this.setLocation(x, y);
        this.setSize(diameter, diameter);
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.red);
        g.fillOval(0, 0, width, height);
    }
}
like image 126
Cruncher Avatar answered Sep 22 '22 17:09

Cruncher