10
votes

Comment puis-je supprimer un JPanel d'un jframe?

Récemment, j'ai demandé ici Comment ajouter un nouveau JPanel à JFRAME . La réponse m'a aidé à obtenir un code de travail. Mais pas j'ai une question connexe: "Comment puis-je supprimer un vieux JPanel". J'ai besoin de cela à cause du problème suivant.

Un nouveau JPanel apparaît apparaît lorsque je veux (la limite de temps est dépassée ou appuyez sur le bouton "Soumettre"). Mais en quelques secondes, un élément de l'ancien JPanel apparaît avec le composant du nouveau JPanel. Je ne comprends pas pourquoi cela se produit. P>

Je pensais que c'est parce que je dois à d'autres threads qui mettent à jour la fenêtre. Mais le premier fil ajout simplement l'ancien panneau une fois (donc, il devrait être fini). Et dans le deuxième fil, j'ai une boucle qui est cassée (cela devrait donc être fini). P>

Voici mon code: P>

private Thread controller = new Thread() {
    public void run() {
        // First we set the initial pane (for the selection of partner).
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.getContentPane().add(generatePartnerSelectionPanel());
                frame.invalidate();
                frame.validate();
            }
        });
        // Update the pane for the selection of the parnter.
        for (int i=40; i>0; i=i-1) {
            final int sec = i;
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    timeLeftLabel.setText(sec + " seconds left.");
                }
            });
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) { }

            if (partnerSubmitted) {
                break;
            }
        }
        // For the given user the selection phase is finished (either the time is over or form was submitted).
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.getContentPane().add(generateWaitForGamePanel());
                frame.invalidate();
                frame.validate();
            }
        });

    }
};


1 commentaires

Cela semble être un duplicata de votre propre question: Stackoverflow.com/Questtions/2487658/...


4 Réponses :


0
votes

Roman, le problème peut être résolu comme celui-là:

  1. Faites-le au début de votre Exécuter Méthode:

    final jPanel PartnersPanel = GeneratePartnerselectionPanel ();

    1. alors faites ceci

      cadre.getContentPane (). Ajouter (PartnerselectionPanel);

      1. Avant d'ajouter le nouveau panneau, faites ceci:

        partenaireselectionPanel.setVisible (Faux);

        Ça marche. Je ne sais pas s'il s'agit d'une solution sûre et / ou élégante, mais cela fonctionne.


1 commentaires

Je pense que l'utilisation de SetVisible est une meilleure solution puis en ajoutant et en retirant le panneau.



8
votes

Le moyen le plus simple de supprimer un composant (panneau) à partir d'un conteneur (cadre) consiste à contenir une référence à celui-ci, puis appelez conteneur.remove (composant) code> IE:

private Thread controller = new Thread() {
public void run() {

        final Component panel1 = generatePartnerSelectionPanel();

        // First we set the initial pane (for the selection of partner).
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.getContentPane().add(panel1);
                frame.invalidate();
                frame.validate();
        }
        });
        // Update the pane for the selection of the parnter.
        for (int i=40; i>0; i=i-1) {
            final int sec = i;
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    timeLeftLabel.setText(sec + " seconds left.");
                }
            });
            try {Thread.sleep(1000);} catch (InterruptedException e) {}
            if (partnerSubmitted) {break;}
        }
        // For the given user the selection phase is finished (either the time is over or form was submitted).
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.getContentPane().remove(panel1);
                frame.getContentPane().add(generateWaitForGamePanel());
                frame.invalidate();
                frame.validate();
        }
        });

}
};


4 commentaires

Merci! Je l'ai testé et ça marche! Il semble être meilleur que la solution de minière. Il vaut mieux l'enlever plutôt que de se cacher.


Il existe également removeall () méthode si vous n'avez pas enregistré le lien vers le (s) composant (s).


heureux d'aider Roman. Vous pouvez cliquer sur la case à côté de la réponse si elle résout votre problème. Et oui, RemoveAll fonctionnera bien, à condition que vous n'ayez pas d'autres composants dans le conteneur.


Merci mec que la réponse a fait ma journée! BTW Vous pouvez également utiliser this.revalidate (); au lieu de cadre.invalidate (); cadre.validate ();



8
votes

C'est la même chose que vous ajoutez ou supprimez un composant sur une interface graphique visible: xxx


1 commentaires

revalidate () était ce dont j'avais besoin. Merci.



1
votes

J'ai eu des problèmes avec demandefocusinwindow sur textfield aussi. L'astuce consiste à ne pas construire les composants dans le constructeur jPanel . Mais, faire une méthode de construction et exécuter le code suivant après avoir été ajouté au cadre.

Ceci a fonctionné pour moi: xxx

Si vous souhaitez redimensionner, vous avez besoin de préférés (); sur panneau ou utilisez repeindre () si vous n'avez pas besoin de redimensionner le cadre.


0 commentaires