Après avoir appelé JTabbedPane.removeAll (), le JTabbedPane a toujours x nombre d'onglets?

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

  •  06-07-2019
  •  | 
  •  

Question

Dans mon JTabbedPane , je supprime les onglets de 2 manières différentes:

tabbedPane.remove(index)

et

tabbedPane.removeAll()

Les deux fonctionnent bien en termes de fermeture des onglets. Cependant, j'ai un écouteur de modification sur mon TabbedPane qui rappelle à un autre module de signaler les modifications d'onglets. C’est là que réside le problème.

Lors de l'ajout et de la suppression d'onglets à l'aide de remove (index) , la source TabbedPane de la méthode stateChanged () contient le nombre correct d'onglets lors de la vérification de TabbedPane. getTabCount () .

Toutefois, lorsque vous appelez tabbedPane.getTabCount () après tabbedPane.removeAll () , le nombre est toujours celui qui était présent juste avant le removeAll ( ) .

Quelqu'un a-t-il des suggestions?

Était-ce utile?

La solution

Après avoir examiné le code source, je vois ce qui se passe.

JTabbedPane déclenche ChangeEvents lorsque l'onglet sélectionné est modifié. Mais pour supprimer tous les onglets, il faut d’abord définir l’onglet sélectionné sur -1, puis puis supprime tous les onglets. Ainsi, lorsque ChangeListener intercepte l'événement, tous les onglets sont toujours présents.

Si vous souhaitez connaître le nombre d'onglets à tout moment, je crains que vous n'ayez à parcourir les onglets vous-même et à les supprimer un à un.

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

Autres conseils

Ici vous allez; utilisez plutôt 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());
    }
}

Si vous recherchez le code JTabbedPane (version 6), les deux codes passent par removeTabAt , ce qui devrait diminuer le nombre. Il déclenchera probablement un événement pour chaque onglet, ce qui signifie que le premier événement doit avoir getTabCount () moins le nombre précédant le removeAll () . <. / p>

Êtes-vous certain de l'appel getTabCount () ? Que se passe-t-il si vous supprimez tous les onglets (de la fin) manuellement?

Essayez d'appeler valider ou revalider

Voici un scénario de test permettant d’exposer le problème.

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

Je pense qu'il y a un problème de synchronisation; la sortie est:

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

Il semble que certains événements de modification soient perdus.

Mise à jour : laisser cela en place pour la postérité, mais c'est faux; comme mmyers indique que les événements ne sont déclenchés que lorsque la sélection change.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top