Dopo aver chiamato JTabbedPane.removeAll (), JTabbedPane ha ancora x numero di schede?

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

  •  06-07-2019
  •  | 
  •  

Domanda

Nel mio JTabbedPane , sto rimuovendo le schede in 2 modi diversi:

tabbedPane.remove(index)

e

tabbedPane.removeAll()

Entrambi funzionano bene in termini di chiusura delle schede. Tuttavia, ho un listener di modifiche sul mio TabbedPane che richiama un altro modulo per segnalare le modifiche alle schede. Questo è dove si trova il problema.

Quando si aggiungono e si rimuovono le schede usando remove (index) , il TabbedPane di origine nel metodo stateChanged () contiene il numero corretto di tab quando si seleziona tabbedPane. getTabCount () .

Tuttavia, quando si chiama tabbedPane.getTabCount () dopo tabbedPane.removeAll () , il conteggio è ancora il conteggio presente immediatamente prima del removeAll ( ) .

Qualcuno ha qualche suggerimento?

È stato utile?

Soluzione

Dopo aver visto il codice sorgente, vedo cosa sta succedendo.

JTabbedPane attiva ChangeEvents quando viene modificata la scheda selezionata. Ma per rimuovere tutte le schede, prima imposta la scheda selezionata su -1 e quindi rimuove tutte le schede. Quindi quando ChangeListener rileva l'evento, tutte le schede sono ancora lì.

Se vuoi conoscere il numero di schede in ogni momento, temo che dovrai scorrere tu stesso le schede e rimuoverle una per una.

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

Altri suggerimenti

Ecco qua; usa invece 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());
    }
}

Guardando il codice JTabbedPane (versione 6) entrambi i codici passano attraverso removeTabAt , il che dovrebbe diminuire il conteggio. Probabilmente genererà un evento per ogni scheda, tuttavia, il che significa che il primo evento dovrebbe avere getTabCount () uno in meno del conteggio prima di removeAll () .

Sei sicuro della chiamata getTabCount () ? Cosa succede se rimuovi manualmente tutte le schede (dalla fine)?

Prova a chiamare validate o revalidate

Ecco un caso di prova che aiuta a esporre il 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());
    }
}

Penso che ci sia un problema di sincronizzazione in corso; l'output è:

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

Sembra che alcuni eventi di modifica vadano persi.

Aggiorna : lasciare questo posto per i posteri, ma è sbagliato; come mmyers sottolinea che gli eventi si attivano solo quando la selezione cambia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top