Tuesday 5 December 2017

java - What is the relation between ContentPane and JPanel?

itemprop="text">


I found one example in
which buttons are added to panels (instances of JPanel) then
panels are added to the the containers (instances generated by
getContentPane()) and then containers are, by the construction,
included into the JFrame (the
windows).



I tried two things:




  1. I got rid of the
    containers. In more details, I added buttons to a panel (instance of
    JPanel) and then I added the panel to the windows (instance of
    JFrame). It worked
    fine.


  2. I got rid of the panels. In more
    details, I added buttons directly to the container and then I added the container to the
    window (instance of
    JFrame).





So,
I do not understand two
things.




  1. Why do we
    have two competing mechanism to do the same
    things?


  2. What is the reason to use
    containers in combination with the panels (JPanel)? (For
    example, what for we include buttons in JPanels and then we include JPanels in the
    Containers). Can we include JPanel in
    JPanel? Can we include a container in
    container?




ADDED:



Maybe
essence of my question can be put into one line of
code:




frame.getContentPane().add(panel);


What
for we put getContentPane() in between? I tried just
frame.add(panel); and it works
fine.



ADDED
2:



I would like to add some code
to be more clear about what I mean. In this example I use only
JPane:




import
java.awt.*;
import javax.swing.*;
public class HelloWorldSwing
{
public static void main(String[] args) {
JFrame frame = new
JFrame("HelloWorldSwing");
JPanel panel = new JPanel();

panel.setLayout(new BorderLayout());
panel.add(new JButton("W"),
BorderLayout.NORTH);
panel.add(new JButton("E"),
BorderLayout.SOUTH);
frame.add(panel);


frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();
frame.setVisible(true);

}
}


And in
this example I use only Content
Pane:



import
java.awt.*;

import javax.swing.*;
public class
HelloWorldSwing {
public static void main(String[] args) {
JFrame
frame = new JFrame("HelloWorldSwing");
Container pane =
frame.getContentPane();
pane.setLayout(new BorderLayout());

pane.add(new JButton("W"), BorderLayout.NORTH);
pane.add(new JButton("E"),
BorderLayout.SOUTH);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();

frame.setVisible(true);

}
}


Both
work fine! I just want to know if between these two ways to do things one is better
(safer).



Answer




It's not two competing mechanisms - a
JPanel is a
Container (just look at the class hierarchy at the top of the
rel="noreferrer">JPanel javadocs).
JFrame.getContentPane() just returns a
Container to place the Components that
you want to display in the JFrame. Internally, it's using a
JPanel (by default - you can change this by calling
setContentPane()) As for why it's returning a
Container instead of a JPanel - it's
because you should href="https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface">program
to an interface, not an implementation - at that level, all that you need to
care about is that you can add Components to something - and
even though Container is a class rather than an interface - it
provides the interface needed to do exactly
that.



As for why both
JFrame.add() and
JFrame.getContentPane().add() both do the same thing -
JFrame.add() is overridden to call
JFrame.getContentPane().add(). This wasn't always the case -
pre-JDK 1.5 you always had to specify
JFrame.getContentPane().add() explicitly and
JFrame.add() threw a RuntimeException
if you called it, but due to many complaints, this was changed in JDK 1.5 to do what
you'd expect.



No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...