在调用JTabbedPane.removeAll()之后,JTabbedPane仍有x个选项卡?

时间:2009-06-18 15:47:08

标签: java swing jtabbedpane

在我的JTabbedPane中,我将以两种不同的方式删除标签:

tabbedPane.remove(index)

tabbedPane.removeAll()

两者在关闭标签方面都很好。但是,我的TabbedPane上有一个更改侦听器,它会调用另一个模块来报告选项卡更改。这就是问题所在。

使用remove(index)添加和删除标签时,stateChanged()方法中的来源TabbedPane在检查tabbedPane.getTabCount()时包含正确数量的标签。

但是,在tabbedPane.getTabCount()之后调用tabbedPane.removeAll()时,计数仍然是紧接removeAll()之前的计数。

有人有任何建议吗?

5 个答案:

答案 0 :(得分:9)

查看源代码后,我看到发生了什么。

更改所选选项卡时,

JTabbedPane将触发ChangeEvents。但是要删除所有选项卡,它首先将选定的选项卡设置为-1,然后然后删除所有选项卡。因此,当ChangeListener捕获事件时,所有选项卡仍然存在。

如果你想知道任何时候标签的数量,我担心你必须自己迭代标签并逐一删除它们。

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

答案 1 :(得分: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());
    }
}

答案 2 :(得分:0)

查看JTabbedPane代码(版本6),两个代码都会通过removeTabAt,这会减少计数。它可能会触发每个标签的事件,但这意味着第一个事件的getTabCount()应该比removeAll()之前的计数少。

您确定getTabCount()来电吗?如果您手动删除所有标签(从末尾)会发生什么?

答案 3 :(得分: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所指出的那样,事件只会在选择发生变化时触发。

答案 4 :(得分:0)

尝试拨打validaterevalidate