Question

En termes simples, il existe une application Java Swing simple composée de JFrame et de certains composants. L’un des composants est un JPanel qui doit être remplacé par un autre JPanel lors d’une action de l’utilisateur.

Alors, quelle est la bonne façon de faire une telle chose? J'ai essayé

panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();

mais cela ne fonctionnera pas. Que suggéreriez-vous?

Était-ce utile?

La solution

Votre cas d'utilisation semble parfait pour CardLayout . .

Dans la présentation des cartes, vous pouvez ajouter plusieurs panneaux au même endroit, puis les afficher ou les masquer, un panneau à la fois.

Autres conseils

1) Configuration du premier panneau:

JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());

2) Remplacement du panneau:

frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());

Notez également que vous devez effectuer cette opération dans le fil de discussion de l'événement. Pour vous en assurer, utilisez le SwingUtilities.invokeLater ou le SwingWorker

frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.

N'oubliez pas que Java utilise l'argument 'Copier référence par valeur'. Ainsi, changer une variable ne changera pas les copies de la référence passée à d’autres méthodes.

Notez également que JFrame est très déroutant en ce qui concerne le nom de facilité d'utilisation. L'ajout d'un composant ou la configuration d'une présentation (généralement) effectue l'opération dans le volet de contenu. Curieusement, obtenir la disposition vous donne vraiment le gestionnaire de disposition du cadre.

J'espère que ce morceau de code vous donnera une idée de la modification de jPanels dans un cadre JFrame.

public class PanelTest extends JFrame {

        Container contentPane;

        public PanelTest()  {
           super("Changing JPanel inside a JFrame");
           contentPane=getContentPane();
        }

        public void createChangePanel() {
           contentPane.removeAll();
           JPanel newPanel=new JPanel();
           contentPane.add(newPanel);
           System.out.println("new panel created");//for debugging purposes
           validate();
           setVisible(true);
        }
}

Sur l'action de l'utilisateur:

// vous devez faire quelque chose dans le sens de

myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()

myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()

Ensuite, vous pouvez redimensionner votre fenêtre à votre guise.

Tout dépend de la manière dont il va être utilisé. Si vous souhaitez basculer entre ces deux panneaux, utilisez un CardLayout. Si vous passez seulement du premier au deuxième une fois (et ne revenez pas), j’utiliserais alors la suggestion de telcontar et juste le remplacer. Bien que si le JPanel ne soit pas la seule chose dans votre cadre, j'utiliserais remove (java .awt.Component) au lieu de removeAll.

Si vous vous trouvez quelque part entre ces deux cas, il s’agit essentiellement d’un compromis espace-temps. CardLayout vous fera gagner du temps, mais utilisera plus de mémoire en gardant à tout moment tout cet autre panneau en mémoire. Mais si vous ne remplacez que le panneau lorsque vous en avez besoin et que vous le construisez à la demande, vous n'avez pas besoin de garder cette mémoire, mais cela prend plus de temps pour passer.

Vous pouvez aussi essayer un JTabbedPane pour utiliser des onglets (c'est encore plus facile que CardLayout car il gère l'affichage / le masquage automatiquement)

Les autres individus ont répondu à la question. Je tiens à vous suggérer d'utiliser un JTabbedPane au lieu de remplacer le contenu. En règle générale, il est mauvais que des éléments visuels de votre application disparaissent ou soient remplacés par un autre contenu. Il existe certes des exceptions à chaque règle, et seuls vous et votre communauté d'utilisateurs pouvez décider de la meilleure approche.

Problème : mon composant n'apparaît pas après l'avoir ajouté au conteneur.

Vous devez appeler revalider et repeindre après avoir ajouté un composant avant qu'il n'apparaisse dans votre conteneur.

Source: http://docs.oracle.com/javase/ tutorial / uiswing / layout / problèmes.html

J'avais exactement le même problème !! Increadible !! La solution que j'ai trouvée était:

  1. Ajout de tous les composants (JPanels) au conteneur;
  2. Utiliser la méthode setVisible (false) pour tous;
  3. En cas d'action de l'utilisateur, définissez setVisible (true) sur le panneau que je voulais. afficher.
// Hiding all components (JPanels) added to a container (ex: another JPanel)
for (Component component : this.container.getComponents()) {
      component.setVisible(false);
}
// Showing only the selected JPanel, the one user wants to see
panel.setVisible(true);

Pas de revalidate (), pas de validate (), pas de CardLayout nécessaire.

La réponse layout.replace () existe / fonctionne uniquement sur GroupLayout Manager.

Les autres responsables de la mise en page (CardLayout, BoxLayout, etc.) NE prennent PAS en charge cette fonctionnalité, mais vous demandent tout d’abord de supprimer RemoveLayoutComponent (puis AddLayoutComponent (à nouveau. :-)

Je vous suggère d'ajouter les deux panneaux lors de la création du cadre, puis de modifier le panneau visible en appelant setVisible (true / false) sur les deux. Lors de l'appel de setVisible, le parent sera avisé et invité à se repeindre.

class Frame1 extends javax.swing.JFrame {

    remove(previouspanel); //or getContentPane().removeAll();

    add(newpanel); //or setContentPane(newpanel);

    invalidate(); validate(); // or ((JComponent) getContentPane()).revalidate();

    repaint(); //DO NOT FORGET REPAINT

}

Parfois, vous pouvez faire le travail sans utiliser la revalidation et parfois sans utiliser le repeindre. Mon conseil: utilisez les deux.

Appelez simplement la méthode pack () après avoir défini le ContentPane , ( java 1.7 , peut-être plus ancien), comme suit:

JFrame frame = new JFrame();  
JPanel panel1 = new JPanel(); 
JPanel panel2 = new JPanel(); 
....
frame.setContentPane(panel1);
frame.pack();
...

frame.setContentPane(panel2);
frame.pack();
...

vous pouvez utiliser la méthode de remplacement d'une présentation:

layout.replace(existingComponent, newComponent)

les composants existants et nouveaux peuvent également être des JPanels.

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