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

发布于 2024-07-24 19:42:08 字数 568 浏览 9 评论 0原文

在我的 JTabbedPane 中,我以两种不同的方式删除选项卡:

tabbedPane.remove(index)

并且

tabbedPane.removeAll()

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

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

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

有没有人有什么建议?

In my JTabbedPane, I am removing tabs in 2 different ways:

tabbedPane.remove(index)

and

tabbedPane.removeAll()

Both work fine in terms of closing the tabs. However, I have a change listener on my TabbedPane that calls back to another module to report on tab changes. This is where the problem is.

When adding and removing tabs using remove(index), the source TabbedPane in the stateChanged() method contains the correct number of tabs when checking tabbedPane.getTabCount().

However, when calling tabbedPane.getTabCount() after tabbedPane.removeAll(), the count is still the count that was present immediately before the removeAll().

Does anyone have any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

满地尘埃落定 2024-07-31 19:42:09

这是一个有助于揭示问题的测试用例。

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 指出的那样,事件仅在选择更改时触发。

Here's a test case that helps to expose the problem.

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());
    }
}

I think there is a synchronization issue going on; the output is:

0 --> 1
1 --> 1
1 --> 0
0 --> 1
1 --> 2

It looks as if some change events are being lost.

Update: leaving this in place for posterity, but it's wrong; as mmyers points out the events only fire when the selection changes.

倦话 2024-07-31 19:42:08

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

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

如果你想随时了解选项卡的数量,恐怕你必须自己迭代选项卡并将其一一删除。

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

After looking at the source code, I see what's happening.

JTabbedPane fires ChangeEvents when the selected tab is changed. But to remove all tabs, it first sets the selected tab to -1 and then removes all the tabs. So when the ChangeListener catches the event, all the tabs are still there.

If you want to know the number of tabs at all times, I'm afraid you'll have to iterate through the tabs yourself and remove them one by one.

while (myTabbedPane.getTabCount() > 0)
    myTabbedPane.remove(0);
对你而言 2024-07-31 19:42:08

干得好; 使用 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());
    }
}

Here you go; use ContainerListener instead:

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());
    }
}
微凉 2024-07-31 19:42:08

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

您确定调用了 getTabCount() 吗? 如果手动删除所有选项卡(从末尾)会发生什么?

Looking a the JTabbedPane code (version 6) both codes go through removeTabAt, which should decrease the count. It probably will fire off an event for each tab, however, meaning that the first event should have the getTabCount() one less then the count before the removeAll().

Are you certain about the getTabCount() call? What happens if you remove all tabs (from the end) manually?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文