Reputation: 107
I came across some code and cannot understand a certain aspect of it although I have done some extensive searching!
My question is: Why are parenthesis used in the middle of a method call?
package com.zetcode;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class QuitButtonExample extends JFrame {
public QuitButtonExample() {
initUI();
}
private void initUI() {
JPanel panel = new JPanel();
getContentPane().add(panel);
panel.setLayout(null);
JButton quitButton = new JButton("Quit");
quitButton.setBounds(50, 60, 80, 30);
quitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
panel.add(quitButton);
setTitle("Quit button");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
QuitButtonExample ex = new QuitButtonExample();
ex.setVisible(true);
}
});
}
}
I am referring to getContentPane().add(panel);
statement. I know what it does, but doesn't really understand how it works. I'm new to Java and have the basics in OO like class fields, class methods, instance fields, instance methods, inner classes, but this one.
Upvotes: 3
Views: 2264
Reputation: 41
This is called method chaining. To understand this a simple example will help you.
String a = "hellloo";
String b = a.toUpperCase().replace("LOO", "O").concat(" WORLD");
System.out.println(b);
This is going to print HELLO WORLD.
Remember the methods in method chaining are processed from left to right.
Above it executes as
toUpperCase()
- "HELLLOO"replace("LOO", "O")
- "HELLO"concat(" WORLD")
- "HELLO WORLD"Similarly for the above code we first get the ContentPane and then add a panel to it.
This reduces the amount of code required to achieve it.
Normally it would be like
Container container = getContentPane();
container.getContentPane();
Chaining reduces the code in half.
Hope this helps.
Upvotes: 2
Reputation: 22670
The Java Language Specification may be a bit formal, but as a developer, you are going to deal with a lot of formal grammars, so let me point out the relevant rules and interpret them:
The syntax of a method invocation defines that parentheses are mandatory:
MethodInvocation:
MethodName ( ArgumentList? )
Primary . NonWildTypeArguments? Identifier ( ArgumentList? )
...
A Primary
expression can be a MethodInvocation
, so method invocations returning objects can be "chained":
Primary:
PrimaryNoNewArray
...
PrimaryNoNewArray:
...
MethodInvocation
...
Upvotes: 1
Reputation: 538
getContentPane()
is a method in JFrame
and returns an object (a ContentPane
), which has a method add()
, which in turn takes a ref to a JPanel
object as its parameter. Pretty straight forward in the end.
Since getContentPane()
belongs to the current object, it would be a bit clearer if the code were written as
this.getContentPane().add(panel);
To follow up on things like this it is a good idea to look in the Javadoc. e.g. API for JSE7
Upvotes: 0
Reputation: 94499
getContentPane()
is a method being invoked on this
. Since it is a method it must be invoked using parenthesis.
In Java, this
refers to the current instance of an object and can be omitted when calling methods in the current class. Since QuitButtonExample
extends the JFrame
class it is able to call all protected and public methods of JFrame
.
So you may not see the getContentPane()
method on the class you are working on, but the method is available further up the class hierarchy and is exposed through the inheritance relationship with JFrame
.
Also, the getContentPane()
method returns an object of type Container
, which we may also invoke methods upon. When an object is received from a method and another method is instantly invoked such as getContentPane().add(panel)
this is known as chaining. It is not necessary to store each object returned from a method to a variable, we can simply use the object returned from the invoked method without assigning it to a stored variable.
Upvotes: 1
Reputation: 200206
This is what the common idiom, called method chaining, looks like.
getContentPane().add(panel);
parses as
Container c = this.getContentPane();
c.add(panel);
The parens indicate a method call, and its return value is used in-place as the this
object for the next method call (add
).
Upvotes: 9
Reputation: 3182
getContentPane().add(panel);
The getContentPane
method has no input parameters, so you have to call it with empty parenthesis to make java compiler happy. After that you make a add(panel)
call on the result of getContentPane
-call.
Upvotes: 1