Depois de chamar JTabbedPane.removeAll (), o JTabbedPane ainda tem x número de guias?

StackOverflow https://stackoverflow.com/questions/1013479

  •  06-07-2019
  •  | 
  •  

Pergunta

Na minha JTabbedPane, estou removendo guias de 2 maneiras diferentes:

tabbedPane.remove(index)

e

tabbedPane.removeAll()

Ambos funcionam muito bem em termos de fechar as abas. No entanto, eu tenho um ouvinte de alteração no meu TabbedPane que chama de volta para outro módulo de relatório sobre a evolução da guia. Este é onde está o problema.

Quando a adição e remoção de abas usando remove(index), o TabbedPane fonte no método stateChanged() contém o número correcto de guias ao verificar tabbedPane.getTabCount().

No entanto, ao chamar tabbedPane.getTabCount() após tabbedPane.removeAll(), a contagem ainda é a contagem que estava presente imediatamente antes do removeAll().

Alguém tem alguma sugestão?

Foi útil?

Solução

Depois de olhar para o código-fonte, eu ver o que está acontecendo.

incêndios JTabbedPane ChangeEvents quando a guia selecionada é alterado. Mas para remover todas as guias, primeiro ele define o guia selecionado para -1 e então remove todas as guias. Assim, quando o ChangeListener pega o evento, todas as guias ainda estão lá.

Se você quer saber o número de guias em todos os momentos, eu tenho medo que você vai ter que percorrer os guias-se e removê-los um por um.

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

Outras dicas

Aqui você vai; uso ContainerListener vez:

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

Olhando um código do JTabbedPane (versão 6) ambos os códigos passam por removeTabAt, o que deve diminuir a contagem. Ele provavelmente irá disparar um evento para cada guia, no entanto, o que significa que o primeiro evento deve ter a getTabCount() um a menos, em seguida, a contagem antes do removeAll().

Você tem certeza sobre a chamada getTabCount()? O que acontece se você remover todas as guias (do fim) manualmente?

Tente chamar Validar ou revalidate

Aqui está um caso de teste que ajuda a expor o problema.

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

Eu acho que existe um problema de sincronização acontecendo; a saída é:

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

Parece que alguns eventos de alteração estão sendo perdidas.

Atualizar : deixar este no lugar para a posteridade, mas que é errado; como mmyers aponta os eventos somente o fogo quando a seleção é alterada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top