IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Java Discussion :

Remplacer un des JPanel d'une JFrame depuis le JPanel


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Par défaut Remplacer un des JPanel d'une JFrame depuis le JPanel
    Bonjour à tous !
    Je reviens ici car je n'arrive pas à trouver la solution à mon problème sur le net. Sans doute à cause du fait que je ne sais pas trop comment formuler ma question.

    Voici mon problème :
    Dans mon programme, j'ai créé une JFrame dans laquelle j'ai inséré 1 JPanel qui contient lui-même 3 JPanel via un BorderLayout (panHaut, panCentral et panBas). Chacun de ces JPanel possède sa propre classe.
    Le JPanel panCentral possède un JLabel et deux JButton agencés via un GridBagLayout.
    Ce que je souhaite c'est que l'un des bouton me permette de remplacer entièrement le contenu du panCentral. Mais je ne vois pas comment procéder.

    Voici un code simplifié de ce que j'ai fait (je ne peux pas poster mon véritable code car il est plus que bordélique, je ne l'ai pas nettoyé et j'ai testé beaucoup de choses que je n'ai pas encore effacé) :

    La JFrame :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class maJFrame extends JFrame {
            private panGeneral pang = new panGeneral();
     
            public maJFrame() {
                    this.setTitle("Test");
    	        this.setSize(1500, 1000);
    	        this.setLocationRelativeTo(null);
    	        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    	        this.setResizable(false);
    	        this.setContentPane(pang);
    	}
    }
    Le JPanel qui contient les trois autres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class panGeneral extends JPanel {
            JPanel panHaut = new PanHaut();
            JPanel panCentral = new PanCentral();
            JPanel panBas = new PanBas();
     
            public panGeneral() {
                    this.setLayout(new BorderLayout());
                    this.add(panHaut, BorderLayout.NORTH);
                    this.add(panCentral, BorderLayout.CENTER);
                    this.add(panBas, BorderLayout.SOUTH);
            }
    }
    Le JPanel panCentral qui contient le bouton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class PanCentral extends JPanel {
            JButton bouton = new JButton("Changer de contenu");
     
            public PanCentral() {
                    this.setLayout(new GridBagLayout());
    //je passe le positionnement du bouton...
                    bouton.addActionListener...
    A partir de là je ne sais pas comment m'y prendre. J'ai l'impression que ce qu'il faudrait c'est que dans l'ActionListener (sous ActionPerformed) j'arrive à transformer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    JPanel panCentral = new PanCentral();
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    JPanel panCentral = new PanCentral2();
    puis ensuite demander à mon JPanel panGeneral de faire un repaint();
    C'est ce qu'il faut faire ?
    Comment on peut faire ça ?

    Je vous remercie d'avance pour votre aide !

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Ce n'est pas le JPanel panCentral = new PanCentral(); qui place le "pancentral" au milieu du "panGeneral ", c'est le this.add(panCentral, BorderLayout.CENTER);. Donc JPanel panCentral = new PanCentral2();, quelque soit l'endroit où tu comptes le mettre ne suffirait pas à changer le composant central du "panGeneral". Pour changer le composant, il faudrait retirer le composant se trouvant déjà dans le centre (le premier ajouté), puis mettre un nouveau à la place, ce qui oblige le bouton "PanCentral" à avoir accès au PanGeneral, pour appeler une de ses méthodes pour faire ce changement.

    1. Si les différents panels ne sont pas éphémères, et relativement peu nombreux, et qu'il faut passer de l'un à l'autre régulièrement, il est préférable d'utiliser un CardLayout qui est adapté pour afficher alternativement différents composants : on les créer une fois au début, on les place tous dans leur conteneur, et on choisit celui qu'on veut afficher quand on veut. Regarde cette discussion, il y a différents exemples.
    2. L'autre solution consiste donc à faire des méthodes dans PanGeneral, du genre :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      public void displayPanCentral2() {
           this.remove(panCentral); // retire le panneau central actuel
           panCentral = new PanCentral2(this); // créé un nouveau paneau de type 2
           this.add(panCentral); // ajouter le panneau au centre (le BorderLayout.CENTER n'est pas nécessaire dans ce cas)     
           this.revalidate();
           this.repaint();
      }
      les PanCentral et PanCentral2 devrait avoir un paramètre au constructeur de type PanGeneral, pour pouvoir l'invoquer dans l'ActionListener:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      public class PanCentral {
          private JButton bouton = new JButton("Changer de contenu");
          public PanCentral(PanGeneral parent) {
                      this.setLayout(new GridBagLayout());
      //je passe le positionnement du bouton...
                      bouton.addActionListener(e-> parent.displayPanCentral2());
          }
      }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Par défaut
    Je pensais qu'en remplaçant "JPanel panCentral = new PanCentral();" par "JPanel panCentral = new PanCentral2();", suite à un repaint() le JPanel général serait reconstruit avec la nouvelle valeur de panCentral.

    En fait, mon programme sera une sorte de jeu dont vous êtes le héros. Quand on lance le programme on tombe sur une fenêtre avec un bandeau en haut qui contiendra diverses infos comme le nom du joueur, un bandeau en bas avec d'autre infos et un contenu central qui contiendra l'histoire et les éléments nécessaires à faire un choix. C'est ce contenu central qui changera constamment au fil du jeu, les bandeaux restent fixes.
    J'ai pensé au CardLayout au début mais il risque d'y avoir beaucoup de panels...

    J'ai dégrossi un peu mon code, je le poste comme ça on parlera tous des mêmes variables, ce sera plus simple.

    Classe "Main"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class Main {
    	public static void main(String[] args) {
    		FenestreMainGame fMainGame = new FenestreMainGame();
    		fMainGame.setVisible(true);
    	}
    }
    Classe "FenestreMainGame" (la JFrame)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class FenestreMainGame extends JFrame {
    	private PanMainGame3 panMG = new PanMainGame3();
     
    	Toolkit t = this.getToolkit();
    	Dimension d = t.getScreenSize();
    	int wr = d.width;
    	int hr = d.height;
    	int wf = (wr*80)/100;
    	int hf = (hr*80)/100;
     
    	public FenestreMainGame() {
    	        this.setTitle("Game Test");
    	        this.setSize(wf, hf);
    	        this.setLocationRelativeTo(null);
    	        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    	        this.setResizable(false);
     
    	        this.setContentPane(panMG);
    	}
    }
    Classe "PanMainGame3" (le JPanel qui contient tous les autres)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    public class PanMainGame3 extends JPanel {
    	JPanel panHaut = new JPanel();
    	JPanel panContenu = new PanMainGame();
    	JPanel panBas = new JPanel();
     
    	Toolkit t = this.getToolkit();
    	Dimension d = t.getScreenSize();
    	int hr2 = d.height;
    	int wr2 = d.width;
    	int wf = (wr2*80)/100;
    	int hf = (hr2*80)/100;
    	double hPanHautC = (hr2*100)/1080;
    	int hPanHaut = (int) hPanHautC;
    	double hPanBasC = (hr2*100)/1080;
    	int hPanBas = (int) hPanBasC;
     
    	double calcecart = (hr2*150)/1080;
    	int ecart = (int) calcecart;
    	double calccols = (wr2*100)/1920;
    	int cols = (int) calccols;
    	double calcwbout = (wr2*300)/1920;
    	int wbout = (int) calcwbout;
    	double calchbout = (hr2*200)/1080;
    	int hbout = (int) calchbout;
    	double calctftitle = (wr2*88)/1920;
    	int tftitle = (int) calctftitle;
    	double calctfbout = (wr2*40)/1920;
    	int tfbout = (int) calctfbout;
     
    	JLabel fake = new JLabel();
    	JLabel fake2 = new JLabel();
     
    	public PanMainGame3() {
     
    		this.setBackground(Color.DARK_GRAY);
    		this.setLayout(new BorderLayout());
     
    		fake.setPreferredSize(new Dimension(1, hPanHaut));
    		panHaut.add(fake);
    		panHaut.setBackground(Color.GRAY);
    		this.add(panHaut, BorderLayout.NORTH);
     
    		fake2.setPreferredSize(new Dimension(100, hPanBas));
    		fake2.setText("En phase de test");
    		fake2.setHorizontalAlignment(SwingConstants.SOUTH_EAST);
    		fake2.setVerticalAlignment(SwingConstants.BOTTOM);;
    		fake2.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 5));
    		panBas.setLayout(new BorderLayout());
    		panBas.add(fake2, BorderLayout.PAGE_END);
    		panBas.setBackground(Color.GRAY);
    		this.add(panBas, BorderLayout.SOUTH);
     
    		panContenu.setBackground(Color.DARK_GRAY);
    		this.add(panContenu, BorderLayout.CENTER);
    	}
     
    	public void displayPanDebut() {
    		this.remove(panContenu);
    		panContenu = new PanDebut();
    		this.add(panContenu);
    		this.revalidate();
    		this.repaint();
    	}
    }
    La classe "PanMainGame" qui est le contenu central amené à être remplacé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    public class PanMainGame extends JPanel {
    	JLabel titleGame = new JLabel();
    	JButton newGame = new JButton();
    	JButton loadGame = new JButton();
    	JButton boutbab = new JButton();
    	JButton boutmid = new JButton();
    	JButton bouttrib = new JButton();
     
    	Toolkit t = this.getToolkit();
    	Dimension d = t.getScreenSize();
    	int hr2 = d.height;
    	int wr2 = d.width;
    	double calcecart = (hr2*100)/1080;
    	int ecart = (int) calcecart;
    	double calccols = (wr2*100)/1920;
    	int cols = (int) calccols;
    	double calcwbout = (wr2*300)/1920;
    	int wbout = (int) calcwbout;
    	double calchbout = (hr2*200)/1080;
    	int hbout = (int) calchbout;
    	double calctftitle = (wr2*88)/1920;
    	int tftitle = (int) calctftitle;
    	double calctfbout = (wr2*40)/1920;
    	int tfbout = (int) calctfbout;
     
    	public PanMainGame() {
    		this.setBackground(Color.DARK_GRAY);
     
    		titleGame.setText("EXEMPLE DE TITRE");
    		titleGame.setFont(new java.awt.Font(Font.SERIF, Font.BOLD, tftitle));
    		titleGame.setForeground(Color.BLACK);
    		titleGame.setBackground(Color.GRAY);
    		titleGame.setVerticalAlignment(SwingConstants.NORTH);
    		titleGame.setVisible(true);
     
    		newGame.setText("<html><center>Nouvelle<br>partie</center></html>");
    		newGame.setFont(new java.awt.Font(Font.SERIF, Font.PLAIN, tfbout));
    		newGame.setFocusPainted(false);
    		newGame.setPreferredSize(new Dimension(wbout, hbout));
    		newGame.setBackground(Color.GRAY);
    		newGame.setForeground(Color.BLACK);
    		newGame.setBorder(BorderFactory.createLineBorder(Color.GRAY));
     
    		loadGame.setText("<html><center>Charger<br>une partie</center></html>");
    		loadGame.setFont(new java.awt.Font(Font.SERIF, Font.PLAIN, tfbout));
    		loadGame.setFocusPainted(false);
    		loadGame.setPreferredSize(new Dimension(wbout, hbout));
    		loadGame.setBackground(Color.GRAY);
    		loadGame.setForeground(Color.BLACK);
    		loadGame.setBorder(BorderFactory.createLineBorder(Color.GRAY));
     
    		boutbab.setBackground(Color.DARK_GRAY);
    		boutbab.setPreferredSize(new Dimension(cols, 1));
    		boutbab.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
    		boutmid.setBackground(Color.DARK_GRAY);
    		boutmid.setPreferredSize(new Dimension(cols, 1));
    		boutmid.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
    		bouttrib.setBackground(Color.DARK_GRAY);
    		bouttrib.setPreferredSize(new Dimension(cols, 1));
    		bouttrib.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
     
    		this.setLayout(new GridBagLayout());
     
    		GridBagConstraints gbc = new GridBagConstraints();
     
    		gbc.gridx = 1;
    		gbc.gridy = 2;
    		gbc.gridheight = 1;
    		gbc.gridwidth = 1;
    		this.add(newGame, gbc);
     
    		gbc.gridx = 3;
    		this.add(loadGame, gbc);
     
    		gbc.gridx = 0;
    		gbc.gridy = 1;
    		this.add(boutbab, gbc);
    		gbc.gridx = 4;
    		this.add(bouttrib, gbc);
    		gbc.gridx = 2;
    		this.add(boutmid, gbc);
     
    		gbc.gridx = 0;
    		gbc.gridy = 0;
    		gbc.gridwidth = 5;
    		gbc.fill = GridBagConstraints.VERTICAL;
    		gbc.insets = new Insets(0, 0, ecart, 0);
    		this.add(titleGame, gbc);
     
    		loadGame.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				JFileChooser dialogue = new JFileChooser();
    				dialogue.showOpenDialog(null);
    				System.out.println("Fichier séléctionné : " + dialogue.getSelectedFile());
    			}
    		});
     
    		newGame.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				PanMainGame3.displayPanDebut();
    			}
    		});
    	}
    }
    J'ai intégré ton code.
    Mais du coup, pour chaque changement il doit exister une fonction correspondante dans PanMainGame3. Je pensais qu'il était possible de faire une méthode unique dans laquelle on passe le nom de la classe du nouveau panel en paramètre quand on l'invoque.

    Avec le code que je viens de poster j'ai une erreur dans la classe PanMainGame à la ligne 100 (PanMainGame3.displayPanDebut(); ) : "Cannot make a static reference to the non-static methode displayPanDebut() from the type PanMainGame3". Si je remplace "public PanMainGame() {}" par "public PanMainGame(PanMainGame3 parent) {}" ça ne résoud pas l'erreur précédente et ça rajoute une erreur dans la classe PanMainGame3 à la ligne 3 (JPanel panContenu = new PanMainGame(); ) : "The constructor PanMainGame() is undefined".

    Je pensais que ce serait simple à la base car dans mon précédent programme je changeais de panel aussi mais les boutons étaient dans la JFrame. Changer de panel depuis le panel qui doit disparaître ça devient de suite plus complexe en fait...

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Vahia Voir le message
    Je pensais qu'en remplaçant "JPanel panCentral = new PanCentral();" par "JPanel panCentral = new PanCentral2();", suite à un repaint() le JPanel général serait reconstruit avec la nouvelle valeur de panCentral.
    ce code ne fait que déclarer une variable et l'initialiser en créant une instance de classe. Remplace un code par un autre dans le source n'a pas vraiment de sens au runtime. Oui on peut remplacer le premier code par le deuxième, mais le premier panel ne s'affichera jamais plus. On va pas changer le code à chaque fois qu'on affiche l'un ou l'autre panel ! Donc pour faire du dynamique, il faut procéder autrement. Et l'instanciation ne suffira pas à changer le composant dans le container où l'autre composant a été ajouté avant.

    En fait, mon programme sera une sorte de jeu dont vous êtes le héros. Quand on lance le programme on tombe sur une fenêtre avec un bandeau en haut qui contiendra diverses infos comme le nom du joueur, un bandeau en bas avec d'autre infos et un contenu central qui contiendra l'histoire et les éléments nécessaires à faire un choix. C'est ce contenu central qui changera constamment au fil du jeu, les bandeaux restent fixes.
    Citation Envoyé par Vahia Voir le message
    J'ai pensé au CardLayout au début mais il risque d'y avoir beaucoup de panels...
    Beaucoup, c'est combien ? Après, justement, si c'est vraiment beaucoup, l'autre possibilité est valable, elle demande juste un peu plus de code pour que ça marche nickel. Attention en revanche à la taille de la fenêtre : si les panels sont de tailles différentes, ils pourraient influencer la taille de la fenêtre : c'est un peu plus compliqué à gérer du coup.

    Citation Envoyé par Vahia Voir le message
    J'ai dégrossi un peu mon code, je le poste comme ça on parlera tous des mêmes variables, ce sera plus simple.
    Je jetterais un coup d’œil plus tard. Pas le temps pour le moment.

    Citation Envoyé par Vahia Voir le message
    Mais du coup, pour chaque changement il doit exister une fonction correspondante dans PanMainGame3. Je pensais qu'il était possible de faire une méthode unique dans laquelle on passe le nom de la classe du nouveau panel en paramètre quand on l'invoque.
    Oui et non. On peut faire une seule fonction. Il y a plein de possibilités pour le faire, à commencer par la réflexion, les lambdas, etc.

    Citation Envoyé par Vahia Voir le message
    Avec le code que je viens de poster j'ai une erreur dans la classe PanMainGame à la ligne 100 (PanMainGame3.displayPanDebut(); ) : "Cannot make a static reference to the non-static methode displayPanDebut() from the type PanMainGame3". Si je remplace "public PanMainGame() {}" par "public PanMainGame(PanMainGame3 parent) {}" ça ne résoud pas l'erreur précédente et ça rajoute une erreur dans la classe PanMainGame3 à la ligne 3 (JPanel panContenu = new PanMainGame(); ) : "The constructor PanMainGame() is undefined".
    L'appel d'une méthode non static doit être fait sur une instance, pas une classe. Il faut que je regarde ton code pour te dire exactement là où tu fais une erreur dans le passage de paramètres et comme je l'ai dit précédemment, pas le temps pour l'instant.

    Citation Envoyé par Vahia Voir le message
    Je pensais que ce serait simple à la base car dans mon précédent programme je changeais de panel aussi mais les boutons étaient dans la JFrame. Changer de panel depuis le panel qui doit disparaître ça devient de suite plus complexe en fait...
    La position du bouton ne pose pas de souci tant qu'on travaille avec l'ActionListener qui est déclenché après tout traitement dans le bouton (armement, désarmement, tout ça) donc ça ne devrait pas poser de souci.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    newGame.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				PanMainGame3.displayPanDebut();
    			}
    		});
    Ici tu appelles une méthode d'instance (une méthode non static) en référençant la classe PanMainGame3, alors que c'est une instance de cette classe qu'il faudrait avoir ici. Et c'est justement en la passant au constructeur de PanMainGame que tu pourras l'avoir à disposition.

    Globalement, tu essayes de faire du simili MDA avec des JPanel à l'intérieur d'un JPanel, ce qui n'est pas vraiment un cas d'usage courant et donc il n'y a pas de support tout fait pour faire ça, mais on pourrait faire quelque chose de similaire qui pourrait gérer le truc et simplifier l'écriture du code, à défaut de procéder avec un CardLayout. Quand j'ai un moment je te prépare un brief à ce sujet. En résumé, tu aurais avantage à faire une fabrique qui gère les liens entre composants et leur affichage/"désaffichage".

    Une autre voie serait de faire un composant qui remplacerait le panel courant par un nouveau panel, de manière générique. Je te prépare un brief également dès que j'ai un moment. Ce serait plus simple que le traitement décrit ci-dessus, mais aussi plus restrictif.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Une autre voie serait de faire un composant qui remplacerait le panel courant par un nouveau panel, de manière générique. Je te prépare un brief également dès que j'ai un moment. Ce serait plus simple que le traitement décrit ci-dessus, mais aussi plus restrictif.
    Voici une méthode relativement simple, plutôt restrictive, mais qui a le mérite d'être assez simple à invoquer quelque soit le contexte, puisqu'il suffit d'avoir la référence d'un composant (le bouton par exemple), la classe du conteneur général (dans ton cas (le premier), panGeneral, et dans le mien MainPanel), une fabrique de JPanel sous forme de supplier (laissant donc à l'appelant la possibilité d'instancier comme il veut), et la contrainte, juste pour être un peu moins restrictif. Les restrictions sont que le JPanel qui contient les différents panneaux qui se remplacent les uns les autres doit avoir un BorderLayout, et que ces différents panneaux doivent être des JPanel.

    Par ailleurs, comme tu peux le voir, le nombre de conteneur entre le "panneau" à remplacer, et le bouton importe peu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class SwingUtils {
     
    	public static <P extends JPanel, C extends JPanel> void replaceComponentInBorderLayout(JComponent comp, Class<P> c, Supplier<C> supplier, Object constraint) {
     
    		JPanel container = (JPanel) SwingUtilities.getAncestorOfClass(c, comp);
    		if ( container!=null ) {
    			LayoutManager layout = (LayoutManager) container.getLayout();
    			if ( layout instanceof BorderLayout ) {
    				BorderLayout borderLayout = (BorderLayout) layout;
    				Component current = borderLayout.getLayoutComponent(container, constraint);
    				if ( current!=null ) {
    					container.remove(current);
    				}
    				container.add(supplier.get(), constraint);
    				container.revalidate();
    				container.repaint();
    				return;
    			}
    		}
    		throw new IllegalStateException();
     
    	}
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.FlowLayout;
     
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
     
    public class Demo {
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		JPanel content = new MainPanel();
    		content.add(new Panel1()); // au début j'affiche Panel1
     
    		frame.add(content); // plutôt que de remplacer le contentpane qui n'est pas un simple JPanel, j'ajoute mon conteneur principal au centre du content pane
     
    		frame.setSize(800,600);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
            // le conteneur général
    	public static class MainPanel extends JPanel {
    		public MainPanel() {
    			super(new BorderLayout());
    		}
    	}
     
    	public static class Panel1 extends JPanel {
     
    		public Panel1() {
    			setBackground(Color.ORANGE);
    			setLayout(new BorderLayout());
    			JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
    			add(buttonPanel, BorderLayout.SOUTH);
    			JButton button = new JButton("Afficher VERT");
    			buttonPanel.add(button);
                            // le bouton va remplacer le composant au centre du MainPanel par un Panel2
    			button.addActionListener(e-> 
    			SwingUtils.replaceComponentInBorderLayout(button, MainPanel.class, ()-> new Panel2(), BorderLayout.CENTER));
    		}
     
    	}
     
    	public static class Panel2 extends JPanel {
     
    		public Panel2() {
    			setBackground(Color.GREEN);
    			setLayout(new BorderLayout());
    			JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
    			add(buttonPanel, BorderLayout.NORTH);
    			JButton button = new JButton("Afficher ORANGE");
    			buttonPanel.add(button);
                            // le bouton va remplacer le composant au centre du MainPanel par un Panel1
    			button.addActionListener(e-> 
    			SwingUtils.replaceComponentInBorderLayout(button, MainPanel.class, ()-> new Panel1(), BorderLayout.CENTER));
    		}
     
    	}
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

Discussions similaires

  1. Comment provoquer le pack() d'une Jframe depuis un JPanel sans ref sur la JFrame
    Par cdtkoenig dans le forum Agents de placement/Fenêtres
    Réponses: 4
    Dernier message: 21/07/2008, 19h11
  2. Réponses: 2
    Dernier message: 19/12/2006, 22h55
  3. Adaptation dynamique des composants d'une JFrame
    Par Invité dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 06/12/2006, 22h23
  4. Insérer des données dans une BD depuis un fichier .bat
    Par kurkaine dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 24/11/2006, 08h31
  5. Réponses: 5
    Dernier message: 07/06/2006, 12h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo