3

The overall question is - where does Java store component (buttons, menu items, etc.) objects when they're added to something like a JFrame, JPanel, JMenu? While digging through the documentation I saw something saying they're stored in a list, but I'm still trying to find specific information on that implementation by digging through Oracle's docs. Could someone who already understands it help me to understand?

While moving through Oracle's Java Tutorials I noticed that a single identifier is re-used to create objects of the same type. For example, this creates two separate buttons:

JPanel buttonPnale = new JPanel("Making some buttons");
JButton buttonMaker;

buttonMaker = new JButton("Left button", blueBurstIcon);
buttonPanel.add(buttonMaker);

buttonMaker = new JButton("Right button", orangeBurstIcon);
buttonPanel.add(buttonMaker);

Typically I would have thought I needed to do this:

JButton buttonOne = new JButton("Left button", blueBurstIcon);
JButton buttonTwo = new JButton("Right button", orangeBurstIcon);

Creating a separate identifier to go with each separate object.

Obviously the objects in the first snippet of code are being saved somewhere, I'm just trying to find out where. It must be when I call .add that they're copied - but where are they copied to? If they're added to a JPanel, are they copied into a data structure the JPanel contains? Or to a data structure in part of the JFrame to which the JPanel has been added?

Steve Kuo
  • 61,876
  • 75
  • 195
  • 257
Azoreo
  • 236
  • 1
  • 3
  • 14
  • `buttonMaker` is just a reference to a `JButton`. I'm not sure what you mean by copied. Inside `add()` the components save the reference they were passed. – Thorn G Jun 24 '13 at 15:58
  • I do realize that buttonMaker is an identifier. By copied I mean "establishing a pointer" - since I'm guessing that the specific object isn't duplicated, but rather the pointer or link to it is being thrown into a list. But, where's that list? – Azoreo Jun 24 '13 at 19:45

5 Answers5

3

Most Swing components contain a list of children. The frame has such a list and as soon as you call add() with the button, the button gets added to said list.

No copy is being made. Both the (unnamed) reference in the list and the named reference buttonMaker point to the same instance in memory. Some languages call buttonMaker an "alias" to stress the fact that it's not actually the object or instance itself but rather a name for something that gives you access to the instance.

When you assign a new reference to buttonMaker, then this has no effect on the buttons in the list of the frame.

This also means that Java will always see someone (either the reference buttonMaker or the list) reference the buttons so they won't be garbage collected.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • When I was discussing it with my wife I realized it's just references (been a while since I thought about C.S., what with a new baby and all). I guess what spawned the issue is that looking through the Java Docs, no "list" is listed in the Fields - I figured every data member would be in there. Maybe it's private and not meant to be accessed directly? – Azoreo Jun 24 '13 at 19:47
3

A JPanel inherits from java.awt.Container, which maintains an internal list of client components (your JButtons in this case). You can find this list in the source code of Container:

/**
 * The components in this container.
 * @see #add
 * @see #getComponents
 */
private java.util.List<Component> component = new java.util.ArrayList<Component>();

Components are added by the protected void addImpl(...) method, which is invoked from the public Component add(Component comp) method in Container.

So it's all private. You're not supposed to see that. ;-)

T-Bull
  • 2,136
  • 2
  • 15
  • 17
  • Thanks! That's really what I was looking for - an explanation as to why this stuff didn't show up in the Java Docs. After reading an above answer it occurred to me that it's probably private/protected and not meant to be revealed. – Azoreo Jun 24 '13 at 19:50
2

Well your question is a nice one.. but yes a novice one..

Unlike C, Java do not provide you with feature to traverse through the basic memory blocks known as pointers in C. But yes, the concept remains safe.

This is because when we talk about Multi-Threading, then such a facility (of using pointers in java) will let a memory clash. So that is automatically handled by JVM. To make Java a thread-safe language.

Apart from that what you are asking in the exaple is...

How come two buttons are created?

So, when you see the code in detail, it follows a tree structure, that is, the JPanel is on the top of the tree, and you are simply adding child to it. So it is keeping track of all the child nodes. But however if you just write this code:

JPanel buttonPnale = new JPanel("Making some buttons");
JButton buttonMaker;

buttonMaker = new JButton("Left button", blueBurstIcon);
buttonMaker = new JButton("Right button", orangeBurstIcon);
buttonPanel.add(buttonMaker);

Then the buttonMaker will loose the old record of the button. And will add the newly created button.

Just remember, it follows tree structure, and well pointers (memory management) is completely done by JVM

Veer Shrivastav
  • 5,434
  • 11
  • 53
  • 83
  • Right, the first buttonMaker object isn't referenced anymore and will eventually get cleaned up, while the second one is actually added to a list. – Azoreo Jun 24 '13 at 19:49
  • Look what I will tell you is that it is not a list.. better call it a tree... the reason is... suppose you have 1 `JFrame` and have two `JPanel`s and you add buttons to your `JPanel1` and `JPanel2` so if it would be a list then the structure would come to be as JFrame containing one JPanel which again contains JPanel and then two buttons. But eventually the condition is JFrame has two children (JPanel) and both the JPanel has one child JButton. So better it be a tree rather than List. – Veer Shrivastav Jun 25 '13 at 03:13
  • Yes, the first object is just a reference, and when the object references the other button, then the previous space is automatically cleaned up by the `JVM`, and you need not need to worry about it explicitly as in C. – Veer Shrivastav Jun 25 '13 at 03:14
0

After you add the first buttonMaker, the buttonMaker references another JButton. The first buttonPanel.add(..) method call has no interest in what that buttonMaker variable has been set to afterwards, because the scope of this variable is only at the method level. That variable doesnt exist in the second buttonPanel.add(..) call

Oliver Watkins
  • 12,575
  • 33
  • 119
  • 225
  • I know, I was asking where it's being referenced, which I got an answer to (and which makes me happy)! – Azoreo Jun 24 '13 at 19:52
0

Using new you are creating new button objects.

"It must be when I call .add that they're copied - but where are they copied to? If they're added to a JPanel, are they copied into a data structure the JPanel contains?"

When you are adding these buttons to any JPanel, you are just putting the reference of the button to the JPanel's internal List ( to be specific, you are adding reference to the Container class's component list, because JPanel is a subclass of Container class). Here is the source code of the add method of Container class.

Again I want to emphasize that, there is nothing about copying the object itself to anywhere while adding components to any container. Its just adding the references to an internal list!

Sazzadur Rahaman
  • 6,938
  • 1
  • 30
  • 52
  • I knew using the word "copy" would come back to bite me! I realized that it was just a reference, I was more worried about where the damned list was. Now that people have been showing me the source code it makes much more sense - thanks! – Azoreo Jun 24 '13 at 19:51
  • Still you can see, that not only I suggested you the source code, I also, mentioned the name of the List that is `component`, you were looking for! – Sazzadur Rahaman Jun 25 '13 at 03:41