Nested classes are a concept in Java that allows you to write a class inside a class. These nested classes are divided into two types: static nested classes and non static nested classes. In Java, non-static classes written within a method are referred to as inner classes. These inner classes are useful when there is a condition in which the object of one class depends on the object of another class.
Consider the following example. Right now, most of us use web browsers to access the internet. We also have a lot of tabs open in our web browser right now. Consider that you are browsing in your browser and have several tabs open at the same time. Your web browser was suddenly closed. Are the browser’s tabs still going to exist? No, not at all. As a result, we can conclude that the presence of tabs is entirely dependent on the browser. We have a class for Browser and another for Tabs. Now, in this case, the object of the class Tabs will exist only if we have an object of the class Browser. In such cases, we write the class Tabs within the class Browser.
Because the class Tabs is written inside a class, it becomes the inner class, and the class Browser becomes the outer class because the inner class is written inside it.
So, in situations where the existence of one object is dependent on the existence of another, we use inner classes conclusively.
An inner class is given a special pass to use the outer class’s items. Even the private information. And the inner class can use the outer class’s private variables and methods as if the variables and members were defined in the inner class. That’s why inner classes are so useful—they have most of the benefits of a regular class, but with special access rights.
In the following code snippets, an outer class variable is being used by an inner class:
class OuterClass {
private int num;
class InnerClass {
void useNum() {
num = 23; //use 'num' as if it were a variable of the inner class!
}
} // close inner class
} // close outer class
An instance of an inner class must be tied to an instance of an outer class. A very special case—an inner class defined within a static method—is an exception to this rule. But we’re not going there, and you might never see one of these in your entire Java life.
Remember that when we say an inner class accesses something in the outer class, we really mean an instance of the inner class accessing something in an instance of the outer class. But which instance? Can any arbitrary instance of the inner class access any instance of the outer class’s methods and variables? No!
An inner object on the heap must be linked to a specific outer object.
How To Make An Instance Of An Inner Class?
If you instantiate an inner class from code within an outer class, the inner object will ‘bond’ with the instance of the outer class. If code within a method, for example, instantiates the inner class, the inner object will bond to the instance whose method is running.
An outer class’s code can instantiate one of its own inner classes in the same way that it instantiates any other class… new InnerClass():
class OuterClass {
// The outer class has a private
// instance variable 'num'
private int num;
//Make an instance of the inner class
InnerClass inner = new InnerClass();
public void doSomething() {
// call a method on the inner class
inner.useNum();
}
class InnerClass {
/*The method in the inner class uses the
outer class instance variable 'num', as if 'num'
belonged to the inner class.*/
void useNum() {
num = 23;
}
} // close inner class
} // close outer class
Now we can get the two-button code working!!
import javax.swing.*;
import javafx.beans.property.adapter.JavaBeanFloatPropertyBuilder;
import java.awt.*;
import java.awt.event.*;
// the main GUI class doesn't implement
// ActionListener now
public class GUIDemo4{
JFrame frame;
JLabel label;
public static void main (String[] args) {
GUIDemo4 guiDemo4 = new GUIDemo4();
guiDemo4.drawGUI();
}
public void drawGUI() {
frame = new JFrame();
JButton colorButton = new JButton("Change Color");
/*instead of passing (this) to the
button's listener registration
method, pass a new instance of
the appropriate listener class.
In this case an instance of ColorChangeListener class*/
colorButton.addActionListener(new ColorChangeListener());
JButton labelButton = new JButton("Change Label");
/*instead of passing (this) to the
button's listener registration
method, pass a new instance of
the appropriate listener class.
In this case an instance of LabelChangeListener class*/
labelButton.addActionListener(new LabelChangeListener());
label = new JLabel("A simple label!!");
MyCustomDrawingPanel drawingPanel = new MyCustomDrawingPanel();
frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
frame.getContentPane().add(BorderLayout.CENTER, drawingPanel);
frame.getContentPane().add(BorderLayout.EAST, labelButton);
frame.getContentPane().add(BorderLayout.WEST, label);
frame.setSize(400,300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class ColorChangeListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
} // close inner class
class LabelChangeListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
// inner class knows about ‘label’
label.setText("Label Changed!!");
}
} // close inner class
}
class MyCustomDrawingPanel extends JPanel {
/* The drawing panel's paintComponent() method
is called every time the user clicks.*/
//the code in this method was discussed in RandomCircleDemo
public void paintComponent(Graphics g) {
g.fillRect(0,0,this.getWidth(), this.getHeight());
int redColor = (int) (Math.random() * 256);
int greenColor = (int) (Math.random() * 256);
int blueColor = (int) (Math.random() * 256);
Color randColor = new Color(redColor, greenColor, blueColor);
g.setColor(randColor);
g.fillOval(50,50,100,100);
}
}
Look carefully at the previous program. We have used TWO ActionListeners in a single class – ColorChangeListener & LabelChangeListener! Also note that the inner class gets to use the ‘frame’ instance variable, without having an explicit reference to the outer class object.
Look here for a better understanding of gui: Creating a GUI With Swing.