JTabbedPane.removeAll()を呼び出した後、JTabbedPaneにはまだx個のタブがありますか?

StackOverflow https://stackoverflow.com/questions/1013479

  •  06-07-2019
  •  | 
  •  

質問

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

tabbedPane.remove(index)

and

tabbedPane.removeAll()

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

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

ただし、 tabbedPane.removeAll()の後に tabbedPane.getTabCount()を呼び出す場合、カウントは removeAll( )

提案はありますか?

役に立ちましたか?

解決

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

選択したタブが変更されると、

JTabbedPane ChangeEvents を発生させます。ただし、すべてのタブを削除するには、最初に選択したタブを-1に設定し、 then ですべてのタブを削除します。そのため、 ChangeListener がイベントをキャッチしても、すべてのタブがそこにあります。

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

while (myTabbedPane.getTabCount() > 0)
    myTabbedPane.remove(0);

他のヒント

ここに行きます。代わりに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());
    }
}

JTabbedPane コード(バージョン6)を見ると、両方のコードが removeTabAt を通過し、カウントが減少します。ただし、おそらく各タブのイベントが発生します。つまり、最初のイベントの getTabCount()は、 removeAll()の前のカウントより1つ少ないはずです。

getTabCount()呼び出しについて確かですか?すべてのタブを(最後から)手動で削除するとどうなりますか?

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

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が指摘しているように、イベントは選択が変更されたときにのみ発生します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top