How do I add icon to JTabbedPane tabs?

The following code snippet demonstrates how to create a JTabbedPane component with image icons attached on their tabs. There are two steps that we need to do to achieve this. First we need to load the image icon and after that we need to attach these icons to the tabs.

To create or load an image icon simply create an instance of ImageIcon class. Pass the information about the image location to the constructor of the ImageIcon. In the example below I provide the location of the image using the getClass().getResource() method which will load the images from resources directory.

To add a new tab with image icon attached to the tabs of a JTabbedPane component we are using the addTab(String, Icon, Component) method. The second argument in this method is the image icon of the tab.

Let’s see the code snippet below:

package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;
import java.util.Objects;

public class TabbedPaneWithIcon extends JPanel {
    private TabbedPaneWithIcon() {
        initializeUI();
    }

    private static void showFrame() {
        JPanel panel = new TabbedPaneWithIcon();
        panel.setOpaque(true);

        JFrame frame = new JFrame("Tabbed Pane With Icon Demo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TabbedPaneWithIcon::showFrame);
    }

    private void initializeUI() {
        this.setLayout(new BorderLayout());
        this.setPreferredSize(new Dimension(500, 200));

        JTabbedPane pane = new JTabbedPane();

        ImageIcon tab1Icon = new ImageIcon(Objects.requireNonNull(
                this.getClass().getResource("/images/test-pass-icon.png")));
        ImageIcon tab2Icon = new ImageIcon(Objects.requireNonNull(
                this.getClass().getResource("/images/test-fail-icon.png")));
        ImageIcon tab3Icon = new ImageIcon(Objects.requireNonNull(
                this.getClass().getResource("/images/test-error-icon.png")));

        JPanel content1 = new JPanel();
        JPanel content2 = new JPanel();
        JPanel content3 = new JPanel();

        pane.addTab("Pass", tab1Icon, content1);
        pane.addTab("Fail", tab2Icon, content2);
        pane.addTab("Error", tab3Icon, content3);

        this.add(pane, BorderLayout.CENTER);
    }
}

The directory structure of the project:

kodejava-swing
├─ pom.xml
└─ src
   └─ main
      ├─ java
      │  └─ org
      │     └─ kodejava
      │        └─ swing
      │           └─ TabbedPaneWithIcon.java
      └─ resources
         └─ images
            ├─ test-error-icon.png
            ├─ test-fail-icon.png
            └─ test-pass-icon.png

And here is the result of the code snippet above.

JTabbedPane Tab with Icon Demo

How do I scroll or wrap JTabbedPane tab layout?

JTabbedPane component tab layout policy of can be either set to JTabbedPane.SCROLL_TAB_LAYOUT or JTabbedPane.WRAP_TAB_LAYOUT. This layout policy will control the display of the tabs when the tabs cannot be displayed in one go. By the default the layout policy is set to JTabbedPane.WRAP_TAB_LAYOUT. Changing tab layout policy to JTabbedPane.SCROLL_TAB_LAYOUT makes the tabs scrollable. A button for scrolling left-right or up-down will be displayed in the tabbed pane.

package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;

public class TabbedPaneTabLayoutPolicy extends JPanel {
    public TabbedPaneTabLayoutPolicy() {
        initializeUI();
    }

    public static void showFrame() {
        JPanel panel = new TabbedPaneTabLayoutPolicy();
        panel.setOpaque(true);

        JFrame frame = new JFrame("TabbedPane Tab Layout Policy Demo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TabbedPaneTabLayoutPolicy::showFrame);
    }

    private void initializeUI() {
        this.setLayout(new BorderLayout());
        this.setPreferredSize(new Dimension(400, 200));

        // Creates a JTabbedPane with scroll tab layout policy
        JTabbedPane pane = new JTabbedPane(JTabbedPane.TOP,
                JTabbedPane.SCROLL_TAB_LAYOUT);
        pane.addTab("One", createPanel("One"));
        pane.addTab("Two", createPanel("Two"));
        pane.addTab("Three", createPanel("Three"));
        pane.addTab("Four", createPanel("Four"));
        pane.addTab("Five", createPanel("Five"));
        pane.addTab("Six", createPanel("Six"));
        pane.addTab("Seven", createPanel("Seven"));
        pane.addTab("Eight", createPanel("Eight"));
        pane.addTab("Nine", createPanel("Nine"));
        pane.addTab("Ten", createPanel("Ten"));

        this.add(pane, BorderLayout.CENTER);
    }

    private JPanel createPanel(String title) {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(new JLabel(title), BorderLayout.NORTH);
        return panel;
    }
}

Here is the screenshot of the code snippet created above. You can see that a button at the top right of the tabbed pane is added so that you can scroll to navigate the hidden tabs.

JTabbedPane Tab Layout Policy Demo

How do I change JTabbedPane tab placement position?

By default, the tabs in a JTabbedPane component is placed on the top. But you can place the tabs on every side of the JTabbedPane component, for example it can be on the top, on the right, on the left or on the bottom of the JTabbedPane.

To change the tab placement position you need to set the tab placement when creating an instance of JTabbedPane. The tab placement can be set using the following constant values: JTabbedPane.TOP, JTabbedPane.RIGHT, JTabbedPane.LEFT and JTabbedPane.BOTTOM.

Let’s see the following code snippet to demonstrate it.

package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;

public class TabbedPaneTabPlacement extends JPanel {
    public TabbedPaneTabPlacement() {
        initializeUI();
    }

    public static void showFrame() {
        JPanel panel = new TabbedPaneTabPlacement();
        panel.setOpaque(true);

        JFrame frame = new JFrame("Tabbed Pane Tab Placement Demo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TabbedPaneTabPlacement::showFrame);
    }

    private void initializeUI() {
        this.setLayout(new BorderLayout());
        this.setPreferredSize(new Dimension(500, 200));

        // Creates a JTabbedPane with tabs at the bottom.
        JTabbedPane pane = new JTabbedPane(JTabbedPane.BOTTOM);
        pane.addTab("Tab 1", createPanel("Panel 1"));
        pane.addTab("Tab 1", createPanel("Panel 2"));
        pane.addTab("Tab 3", createPanel("Panel 3"));

        this.add(pane, BorderLayout.CENTER);
    }

    private JPanel createPanel(String title) {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(new JLabel(title), BorderLayout.NORTH);
        return panel;
    }
}

And here is the result of the code snippet above.

JTabbedPane Tab Position Demo

How do I detect tab selection changes in JTabbedPane?

In this example you will learn how to detect tab selection changes in a JTabbedPane component. To get notified when a tab is selected you must add a ChangeListener to the JTabbedPane component using the addChangeListener(). This method take an instance of class that implements the ChangeListener interface as its arguments.

In this example we implement the ChangeListener interface in the TabbedPaneSelection class. And we need to create an implementation for the stateChanged() method as defined by this interface contract. By implementing the interface in the TabbedPaneSelection class, we don’t need to create a separate class that specifically implement this interface. That’s why in the code snippet below we just pass the current object, using the this keyword, when calling the addChangeListener() method.

The stateChanged() method of this interface will be fired every time a new tab is selected. To get the selected tab index you can use the JTabbedPane‘s getSelectedIndex() method. The index returned by the getSelectedIndex() method is zero based, it means that if you select the first tab you will get index of 0, and if you select the second tab you will get index of 1.

package org.kodejava.swing;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;

public class TabbedPaneSelection extends JPanel implements ChangeListener {
    public TabbedPaneSelection() {
        initializeUI();
    }

    public static void showFrame() {
        JPanel panel = new TabbedPaneSelection();
        panel.setOpaque(true);

        JFrame frame = new JFrame("JTabbedPane Selection Demo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TabbedPaneSelection::showFrame);
    }

    private void initializeUI() {
        JTabbedPane tabbedPane = new JTabbedPane();

        JPanel dashboardPanel = new JPanel();
        tabbedPane.addTab("Dashboard", dashboardPanel);

        JPanel accountPanel = new JPanel();
        tabbedPane.addTab("Account", accountPanel);

        this.setLayout(new BorderLayout());
        this.setPreferredSize(new Dimension(500, 200));
        this.add(tabbedPane, BorderLayout.CENTER);

        // Add ChangeListener to the tabbed pane.
        tabbedPane.addChangeListener(this);
    }

    public void stateChanged(ChangeEvent e) {
        JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
        int selectedIndex = tabbedPane.getSelectedIndex();
        JOptionPane.showMessageDialog(null, "Selected Index: " + selectedIndex);
    }
}

If you run the presented code snippet above you’ll get the output as shown in the image below. And if you click the tab a message dialog will be displayed showing you the selected index.

JTabbedPane Selection Demo

How do I create a simple JTabbedPane?

In this example you will learn how to use JTabbedPane to arrange some components in tabbed view. The JTabbedPane component of the Swing API allows some components such as panels to share the same view. By selecting the corresponding tab, the panel will be displayed on the user’s screen. To add tabs to the JTabbedPane class you can use the addTab() method.

To the addTab() method accept two arguments, the title of the tab and the component you wish to display as the content of the tab. In the code snippet below we will use a simple panel as the content of the tab. You can also define an image icon for the tab which makes the program looks better. You can read it in this example:

Now, let’s create a simple example of JTabbedPane which has three tabs and the corresponding content, they are the Dashboard, Transaction and Account tabs. Below is an image that show how the screen will look.

Simple JTabbedPane Demo

package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;

public class SimpleTabbedPane extends JPanel {
    public SimpleTabbedPane() {
        initializeUI();
    }

    public static void showFrame() {
        JPanel panel = new SimpleTabbedPane();
        panel.setOpaque(true);

        JFrame frame = new JFrame("Simple Tabbed Pane Demo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(SimpleTabbedPane::showFrame);
    }

    private void initializeUI() {
        JTabbedPane tabbedPane = new JTabbedPane();

        JPanel dashboardPanel = new JPanel();
        dashboardPanel.add(new JLabel("Dashboard"));

        // Add Dashboard Tab
        tabbedPane.addTab("Dashboard", dashboardPanel);

        JPanel transactionPanel = new JPanel();
        transactionPanel.add(new JLabel("Transaction"));

        // Add Transactions Tab
        tabbedPane.addTab("Transaction", transactionPanel);

        JPanel accountPanel = new JPanel();
        accountPanel.add(new JLabel("Account"));

        // Add Account Tab
        tabbedPane.addTab("Account", accountPanel);

        this.setLayout(new BorderLayout());
        this.setPreferredSize(new Dimension(500, 200));
        this.add(tabbedPane, BorderLayout.CENTER);
    }
}

How do I invoke superclass constructor?

This example shows you how to use the super keyword to call a superclass constructor. The Female class constructor calls its superclass constructor and initializes its own initialization parameters. The call to the superclass constructor must be done in the first line of the constructor in the subclass.

package org.kodejava.example.fundamental;

public class Human {
    private String gender;
    private int age;

    public Human(String gender) {
        this.gender = gender;
    }
}

To call a superclass constructor we call super(). In the case below we call the superclass constructor with one string variable as a parameter.

package org.kodejava.example.fundamental;

public class Female extends Human {
    private String hairStyle;

    public Female(String hairStyle, String gender) {
        super(gender);
        this.hairStyle = hairStyle;
    }
}

How do I create and implement abstract class?

Abstract class is a class that have one or more methods declared, but not defined. Abstract class cannot have instances. This class uses in inheritance to take advantage of polymorphism. To declare that a class is abstract, use the abstract keyword in front of the class keyword in the class definition.

Methods in abstract class that have no definition are called abstract methods. The declaration for an abstract method ends with a semicolon and you specify the method with the abstract keyword to identify it as such. The implementation is left to the sub classes.

package org.kodejava.example.fundamental;

public abstract class Animal {
    private String species;

    public Animal(String species) {
        this.species = species;
    }

    public abstract void makeASound();

    public String getSpecies() {
        return species;
    }

    public static void main(String[] args) {
        Animal pig = new Pig("Warthog");
        pig.makeASound();
    }
}

The Pig class extends the Animal class. Because the Animal class contains an abstract method makeASound() the Pig class must implements this method or else the Pig will also become an abstract class.

package org.kodejava.example.fundamental;

public class Pig extends Animal {

    public Pig(String species) {
        super(species);
    }

    @Override
    public void makeASound() {
        System.out.println("oink oink");
    }
}

How do I override a method in Java?

If a subclass has a method that have the same signature with a method in its superclass, then it’s an overriding method. Override inherited methods allow subclasses to provide specialized implementation for those methods. The overriding method has the same name, number and type of arguments, and return value as the method it overrides.

The overriding method can have a different throws clause as long as it doesn’t specify any types not specified by the throws clause in the overridden method. Also, the access specifier for the overriding method can allow more but not less access than the overridden method.

For example, a protected method in the superclass can be made public but not private. A subclass cannot override methods that are declared final in the superclass. A subclass must override methods that are declared abstract in the superclass, or the subclass itself must be abstract.

package org.kodejava.example.fundamental;

public class Car {
    private String type;
    private String brand;
    private String model;
    private int numberOfSeat;

    public Car() {
    }

    public Car(String type, String brand, String model) {
        this.type = type;
        this.brand = brand;
        this.model = model;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public int getNumberOfSeat() {
        return numberOfSeat;
    }

    public void setNumberOfSeat(int numberOfSeat) {
        this.numberOfSeat = numberOfSeat;
    }

    public String getCarInfo() {
        return"Type: " + type
                + "; Brand: " + brand
                + "; Model: " + model;
    }
}

In the Truck class we override the getCarInfo() method to provide more information about the truck object. We can also add an @Override annotation to an overriding method.

package org.kodejava.example.fundamental;

public class Truck extends Car {
    private int loadCapacity;

    public Truck() {
    }

    public Truck(String type, String brand, String model) {
        super(type, brand, model);
    }

    public int getLoadCapacity() {
        return loadCapacity;
    }

    public void setLoadCapacity(int loadCapacity) {
        this.loadCapacity = loadCapacity;
    }

    @Override
    public String getCarInfo() {
        return "Type: " + getType()
                + "; Brand: " + getBrand()
                + "; Model: " + getModel()
                + "; Load capacity: " + getLoadCapacity();
    }
}

How do I declare and initialize variable?

Variable is a field in which object store its state. It also an allocations for the placement of data in memory. When the statement of variable declaration is compiled, some bytes of memory will be allocated for the variable. The size is determined by the type of variable.

One variable definition is able to store data only of one particular type. Before it can use, the variable must be declared. The name and type of variable must be specified in variable declaration. If you want the variable to have an initial value, you must specify your own value in the declaration.

You can assign a value into variable by using an assignment statement. The assignment operator is =.

package org.kodejava.basic;

public class VariableExample {
    // declares a double variable number1 and total
    private double number1, total;

    // declares a double variable and initializes its value to 10000
    private double number2 = 1000;


    public static void main(String[] args) {
        VariableExample ve = new VariableExample();

        // assigns a value to variable number1
        ve.number1 = 500;

        // assigns the calculation result of number1 + number2 to 
        // total
        ve.total = ve.number1 + ve.number2;
        System.out.println(ve.total);
    }
}

How do I declare and initialize local variable?

Local variables are variables that are not fields of a class. A function or method often store its temporary state in local variables. Local variables only visible to the methods in which they are declared.

Local variables must be declared and initialized before it used for the first time. Local variables will not get a default value if you do not initialize it and could cause a compile-time error.

package org.kodejava.basic;

public class LocalVariableExample {
    // it's okay if total variable does not initialize.
    // it will initialize with default value = 0.
    int total;

    public static int add() {
        // this will cause compile-time error if does not initialize
        int x = 1, y = 2;

        // z is assigned by the calculation result of x + y
        int z = x + y;
        return z;
    }

    public static void main(String[] args) {
        LocalVariableExample lve = new LocalVariableExample();
        // assigns total with the result of add() method execution
        lve.total = add();
        System.out.println("total= " + lve.total);
    }
}