2

私のJTabbedPaneでは、2 つの異なる方法でタブを削除しています。

tabbedPane.remove(index)

tabbedPane.removeAll()

タブを閉じるという点では、どちらも正常に機能します。TabbedPaneただし、タブの変更を報告するために別のモジュールにコールバックする変更リスナーがあります。ここが問題です。

を使用してタブを追加および削除する場合remove(index)、メソッドのソース TabbedPane には、stateChanged()チェック時に正しい数のタブが含まれますtabbedPane.getTabCount()

tabbedPane.getTabCount()ただし、 の後に呼び出すtabbedPane.removeAll()と、カウントは の直前にあったカウントのままremoveAll()です。

誰か提案はありますか?

4

5 に答える 5

10

ソースコードを見た後、何が起こっているかがわかります。

JTabbedPaneChangeEvents選択したタブが変更されたときに発生します。ただし、すべてのタブを削除するには、まず選択したタブを -1 に設定してから、すべてのタブ削除します。そのためChangeListener、 がイベントをキャッチしても、すべてのタブはまだそこにあります。

常にタブの数を知りたい場合は、自分でタブを繰り返し処理し、1 つずつ削除する必要があります。

while (myTabbedPane.getTabCount() > 0)
    myTabbedPane.remove(0);
于 2009-06-18T16:02:46.093 に答える
3

どうぞ; 代わりに ContainerListener を使用します。

import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;

import javax.swing.JPanel;
import javax.swing.JTabbedPane;

import junit.framework.TestCase;

public class JTabbedPaneTest extends TestCase {
    private JTabbedPane pane;
    private int         count   = 0;

    protected void setUp() throws Exception {
        pane = new JTabbedPane();
        ContainerListener containerListener = new ContainerListener() {
            public void componentAdded(ContainerEvent e) {
                count++;
            }

            public void componentRemoved(ContainerEvent e) {
                count--;
            }
        };
        pane.addContainerListener(containerListener);
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
        pane.add(panel1);
        pane.add(panel2);
    }

    public void testOne() throws Exception {
        assertEquals(2, count);
        assertEquals(2, pane.getTabCount());
        pane.remove(0);
        pane.remove(0);
        assertEquals(0, count);
        assertEquals(0, pane.getTabCount());
    }

    public void testMany() throws Exception {
        assertEquals(2, count);
        assertEquals(2, pane.getTabCount());
        pane.removeAll();
        assertEquals(0, count);
        assertEquals(0, pane.getTabCount());
    }
}
于 2009-06-18T16:30:36.593 に答える
0

これが問題を明らかにするのに役立つテストケースです。

import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import junit.framework.TestCase;

public class JTabbedPaneTest extends TestCase {
    private JTabbedPane     pane;
    private int             count = 0;

    protected void setUp() throws Exception {
        pane = new JTabbedPane();
        ChangeListener listener = new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                JTabbedPane pane = (JTabbedPane)e.getSource();
                int before = count;
                count = pane.getTabCount();
                System.out.println(String.format("%s --> %s", before, count));
            }
        };
        pane.addChangeListener(listener);
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
        pane.add(panel1);
        pane.add(panel2);
    }

    public void testOne() throws Exception {
        assertEquals(1, count); // I actually expect 2
        assertEquals(2, pane.getTabCount());
        pane.remove(0);
        pane.remove(0);
        assertEquals(0, count);
        assertEquals(0, pane.getTabCount());
    }

    public void testMany() throws Exception {
        assertEquals(1, count); // I actually expect 2
        assertEquals(2, pane.getTabCount());
        pane.removeAll();
        assertEquals(2, count); // I actually expect 0
        assertEquals(0, pane.getTabCount());
    }
}

同期の問題が発生していると思います。出力は次のとおりです。

0 --> 1
1 --> 1
1 --> 0
0 --> 1
1 --> 2

一部の変更イベントが失われているように見えます。

更新:後世のためにこれを残しますが、それは間違っています。mmyersが指摘しているように、イベントは選択が変更されたときにのみ発生します。

于 2009-06-18T16:12:40.997 に答える
0

検証または再検証を呼び出すようにしてください

于 2009-06-18T16:16:57.753 に答える
0

コード (バージョン 6)を見ると、JTabbedPane両方のコードが通過removeTabAtするため、カウントが減少するはずです。ただし、タブごとにイベントが発生する可能性があります。つまり、最初のイベントgetTabCount()には、removeAll().

getTabCount()通話は確実ですか?すべてのタブ (末尾から) を手動で削除するとどうなりますか?

于 2009-06-18T16:01:34.487 に答える