2

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

tabbedPane.remove(index)

tabbedPane.removeAll()

两者在关闭选项卡方面都可以正常工作。但是,我有一个更改侦听器,TabbedPane它回调另一个模块以报告选项卡更改。这就是问题所在。

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

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

有没有人有什么建议?

4

5 回答 5

10

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

JTabbedPaneChangeEvents更改“选定”选项卡时发射。但是要删除所有选项卡,它首先将选定选项卡设置为 -1,然后删除所有选项卡。因此,当ChangeListener捕获事件时,所有选项卡仍然存在。

如果您想随时知道选项卡的数量,恐怕您必须自己遍历选项卡并逐个删除它们。

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

查看JTabbedPane代码(第 6 版),两个代码都通过removeTabAt,这应该会减少计数。但是,它可能会为每个选项卡触发一个事件,这意味着第一个事件应该getTabCount()removeAll().

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

于 2009-06-18T16:01:34.487 回答
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

尝试调用validaterevalidate

于 2009-06-18T16:16:57.753 回答