Depois de chamar JTabbedPane.removeAll (), o JTabbedPane ainda tem x número de guias?
-
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?
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.