web-dev-qa-db-ja.com

JTabbedPane ChangeListener

選択したタブがいつ変更されるかを検出し、そのインデックスを取得する必要があります。

次のコードは機能しますが、現在ロードされているタブの数だけprintlnを起動します:

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
    }
});

これを行う正しい方法は何ですか?前もって感謝します。

39
vemv

JDK 6 Update 26(Windows 7 64ビット)では、次のデモコードに対して1つのイベントしか取得できません。

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);
}

デバッガーでリスナーが3回トリガーされる理由を理解できますか?

53
belgther

例えば

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() {
    }
}

プリントアウト

run:
Selected paneNo : 1
Selected paneNo : 2
Selected paneNo : 3
BUILD SUCCESSFUL (total time: 7 seconds)
11
mKorbel