Después de llamar a JTabbedPane.removeAll (), ¿el JTabbedPane todavía tiene x número de pestañas?

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

  •  06-07-2019
  •  | 
  •  

Pregunta

En mi JTabbedPane , estoy eliminando pestañas de 2 maneras diferentes:

tabbedPane.remove(index)

y

tabbedPane.removeAll()

Ambos funcionan bien en términos de cerrar las pestañas. Sin embargo, tengo un detector de cambios en mi TabbedPane que llama a otro módulo para informar sobre los cambios en las pestañas. Aquí es donde está el problema.

Al agregar y quitar pestañas usando remove (index) , el TabbedPane de origen en el método stateChanged () contiene el número correcto de pestañas al marcar tabbedPane. getTabCount () .

Sin embargo, cuando se llama a tabbedPane.getTabCount () después de tabbedPane.removeAll () , el recuento sigue siendo el recuento que estaba presente inmediatamente antes del removeAll ( ) .

¿Alguien tiene alguna sugerencia?

¿Fue útil?

Solución

Después de mirar el código fuente, veo lo que sucede.

JTabbedPane dispara ChangeEvents cuando se cambia la pestaña seleccionada. Pero para eliminar todas las pestañas, primero establece la pestaña seleccionada en -1 y luego elimina todas las pestañas. Entonces, cuando ChangeListener detecta el evento, todas las pestañas siguen ahí.

Si quieres saber la cantidad de pestañas en todo momento, me temo que tendrás que recorrer las pestañas tú mismo y eliminarlas una por una.

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

Otros consejos

Aquí tienes; use ContainerListener en su lugar:

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

Buscando el código JTabbedPane (versión 6) ambos códigos pasan por removeTabAt , lo que debería disminuir el conteo. Sin embargo, probablemente disparará un evento para cada pestaña, lo que significa que el primer evento debe tener el getTabCount () uno menos que el conteo antes del removeAll () .

¿Está seguro acerca de la llamada getTabCount () ? ¿Qué sucede si eliminas todas las pestañas (desde el final) manualmente?

Intente llamar a validar o revalidar

Aquí hay un caso de prueba que ayuda a exponer el 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());
    }
}

Creo que hay un problema de sincronización en curso; la salida es:

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

Parece que se están perdiendo algunos eventos de cambio.

Actualización : dejar esto en su lugar para la posteridad, pero está mal; como mmyers señala que los eventos solo se activan cuando cambia la selección.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top