JTabbedPane.removeAll()を呼び出した後、JTabbedPaneにはまだx個のタブがありますか?
-
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が指摘しているように、イベントは選択が変更されたときにのみ発生します。