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

tabbedPane.remove(index)

tabbedPane.removeAll()

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

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

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

有人有任何建议吗?

有帮助吗?

解决方案

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

选择的选项卡更改后,

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

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

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()之前的计数少一个。

您确定 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