45

I need to detect when the selected tab changes, and get its index.

The following code works, but it fires the println as many times as the amount of tabs currently loaded:

tabbedPane.addChangeListener(new ChangeListener() {
    public void stateChanged(ChangeEvent e) {
        System.out.println("Tab: " + tabbedPane.getSelectedIndex());
        // Prints the string 3 times if there are 3 tabs etc
    }
});

What is the correct way of doing this?

İsmail Y.
  • 3,579
  • 5
  • 21
  • 29
deprecated
  • 5,142
  • 3
  • 41
  • 62
  • Check this: http://www.exampledepot.com/egs/javax.swing/tabbed_TpEvt.html Does it help you? – Alberto Solano Jul 23 '11 at 10:38
  • No, in fact it uses the same methods than my example – deprecated Jul 23 '11 at 10:55
  • Sorry, but if you want to detect the id when the selected tab changes, don't you need to know where you have the ChangeEvent, with getSource() ? IMHO, maybe I'm wrong, the code prints out 3 times (if you have 3 tabs) because we don't know the "source" of event. How can you get the id of the selected tab changed when the code doesn't know what tab changed? – Alberto Solano Jul 23 '11 at 11:20
  • tabbedPane.getSelectedIndex(); – deprecated Jul 23 '11 at 14:23
  • You are doing this in the correct way, and I also get multiple events. Is this a problem? – Jonas Jul 23 '11 at 16:02
  • Some database action is linked to `stateChanged` so yes. I could use a counter so only the last event calls the mentioned DB method but maybe there's a clearer way? – deprecated Jul 23 '11 at 19:35

2 Answers2

59

By JDK 6 Update 26 (Windows 7 64-Bit), I only get one event for the following demonstration code:

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setBounds(0, 0, 300, 400);
    frame.setLayout(null);
    final JTabbedPane tabbedPane = new JTabbedPane();
    tabbedPane.addTab("One", new JPanel());
    tabbedPane.addTab("Two", new JPanel());
    tabbedPane.addTab("Three", new JPanel());
    tabbedPane.addChangeListener(new ChangeListener() {
        public void stateChanged(ChangeEvent e) {
            System.out.println("Tab: " + tabbedPane.getSelectedIndex());
        }
    });
    tabbedPane.setBounds(0, 0, 300, 400);
    frame.add(tabbedPane);
    frame.setVisible(true);
}

Can you figure out in the debugger why the listener is triggered three times?

belgther
  • 2,544
  • 17
  • 15
  • 24
    Okay I'm stupid. The code that adds the `ChangeListener` is in the same block that adds a `Tab` so I was adding one listener per tab. – deprecated Jul 24 '11 at 11:16
13

for example

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

public class TestTabbedPane {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                final JPanel ui = new JPanel(new BorderLayout(1, 1));
                JTabbedPane jtp = new JTabbedPane(JTabbedPane.LEFT);
                jtp.addTab("Apple", new JLabel("Apple"));
                jtp.addTab("Banana", new JLabel("Banana"));
                jtp.addTab("Cherries", new JLabel("Cherries"));
                jtp.addTab("Grapes", new JLabel("Grapes"));
                ui.add(jtp, BorderLayout.CENTER);
                jtp.setPreferredSize(new Dimension(200, 200));
                jtp.addChangeListener(new ChangeListener() {

                    @Override
                    public void stateChanged(ChangeEvent e) {
                        if (e.getSource() instanceof JTabbedPane) {
                            JTabbedPane pane = (JTabbedPane) e.getSource();
                            System.out.println("Selected paneNo : " + pane.getSelectedIndex());
                        }
                    }
                });
            }
        };
        SwingUtilities.invokeLater(r);
    }

    private TestTabbedPane() {
    }
}

printOut

run:
Selected paneNo : 1
Selected paneNo : 2
Selected paneNo : 3
BUILD SUCCESSFUL (total time: 7 seconds)
mKorbel
  • 109,525
  • 20
  • 134
  • 319