После вызова JTabbedPane.removeAll () у JTabbedPane все еще есть x вкладок? - PullRequest
2 голосов
/ 18 июня 2009

В моем JTabbedPane я удаляю вкладки двумя разными способами:

tabbedPane.remove(index)

и

tabbedPane.removeAll()

Оба работают нормально с точки зрения закрытия вкладок. Однако на моем TabbedPane есть прослушиватель изменений, который перезванивает в другой модуль, чтобы сообщить об изменениях вкладок. Вот где проблема.

При добавлении и удалении вкладок с помощью remove(index) исходная вкладка TabbedPane в методе stateChanged() содержит правильное количество вкладок при проверке tabbedPane.getTabCount().

Однако, при вызове tabbedPane.getTabCount() после tabbedPane.removeAll(), счет остается тем же счетом, который присутствовал непосредственно перед removeAll().

У кого-нибудь есть предложения?

Ответы [ 5 ]

9 голосов
/ 18 июня 2009

После просмотра исходного кода я вижу, что происходит.

JTabbedPane срабатывает ChangeEvents при изменении выбранной вкладки. Но чтобы удалить все вкладки, сначала для выбранной вкладки устанавливается значение -1, а , а затем - для удаления всех вкладок. Поэтому, когда ChangeListener перехватывает событие, все вкладки все еще там.

Если вы хотите узнать количество вкладок за все время, я боюсь, что вам придется самостоятельно перебирать вкладки и удалять их по одной.

while (myTabbedPane.getTabCount() > 0)
    myTabbedPane.remove(0);
3 голосов
/ 18 июня 2009

Вот, пожалуйста; используйте взамен 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());
    }
}
0 голосов
/ 18 июня 2009

Попробуйте позвонить подтвердить или подтвердить

0 голосов
/ 18 июня 2009

Вот тестовый пример, который помогает выявить проблему.

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

Похоже, что некоторые события изменений теряются.

Обновление : оставить это на месте для потомков, но это неправильно; как отмечает ммерс, события запускаются только при изменении выбора.

0 голосов
/ 18 июня 2009

При поиске кода JTabbedPane (версия 6) оба кода проходят через removeTabAt, что должно уменьшить количество. Однако, вероятно, оно сработает для каждой вкладки, что означает, что первое событие должно иметь на getTabCount() на единицу меньше, чем число до removeAll().

Вы уверены в звонке getTabCount()? Что произойдет, если вы удалите все вкладки (с конца) вручную?

...