How do I add disabled icon for JTabbedPane tabs?

When adding a tabs to JTabbedPane you can define the icon for the tabs. This icon will be displayed beside the tab’s title in enable or disable state of the tabs. To make the user interface better you can also define a disabled icon for the tab. This icon will be displayed when the state of the tabs are disabled.

To assign a disabled icon for the tab use the JTabbedPane‘s setDisabledIconAt(int index, Icon icon) method. As always the index parameter is zero-based which means the first tab is at index number 0. The icon parameter is the disabled icon of your tabs.

package org.kodejava.swing;

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

public class TabbedPaneDisableIcon extends JPanel {
    private final ImageIcon[] disableIcons = {
            new ImageIcon(Objects.requireNonNull(
                    this.getClass().getResource("/images/test-pass-icon-disable.png"))),
            new ImageIcon(Objects.requireNonNull(
                    this.getClass().getResource("/images/test-fail-icon-disable.png"))),
            new ImageIcon(Objects.requireNonNull(
                    this.getClass().getResource("/images/test-error-icon-disable.png"))),
    };

    public TabbedPaneDisableIcon() {
        initializeUI();
    }

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

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

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TabbedPaneDisableIcon::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);

        for (int i = 0; i < pane.getTabCount(); i++) {
            pane.setDisabledIconAt(i, disableIcons[i]);
        }

        // Disable the last tab to see the disabled icon displayed.
        pane.setEnabledAt(pane.getTabCount() - 1, false);

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

The result of the code snippet above is:

Set Disabled Icon for JTabbedPane Tabs

Set Disabled Icon for JTabbedPane Tabs

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